Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 5613479

Browse files
committedMar 19, 2020
chore: init
1 parent 62adee2 commit 5613479

19 files changed

+316
-105
lines changed
 

‎.eslintrc.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ module.exports = {
1818
{
1919
files: [
2020
'**/__tests__/*.{j,t}s?(x)',
21-
'**/tests/unit/**/*.spec.{j,t}s?(x)'
21+
'**/*.spec.{j,t}s?(x)'
2222
],
2323
env: {
2424
jest: true

‎jest.config.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
module.exports = {
2-
preset: '@vue/cli-plugin-unit-jest'
2+
preset: '@vue/cli-plugin-unit-jest',
3+
testMatch: [
4+
'**/*.spec.[jt]s?(x)'
5+
]
36
}

‎package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@
99
"lint": "vue-cli-service lint"
1010
},
1111
"dependencies": {
12+
"axios": "^0.19.2",
1213
"core-js": "^3.6.4",
13-
"vue": "^2.6.11"
14+
"vue": "^2.6.11",
15+
"vuex": "^3.1.3"
1416
},
1517
"devDependencies": {
1618
"@vue/cli-plugin-babel": "^4.2.0",

‎public/index.html

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
<meta name="viewport" content="width=device-width,initial-scale=1.0">
77
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
88
<title><%= htmlWebpackPlugin.options.title %></title>
9+
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
10+
<link rel="stylesheet" href="https://code.getmdl.io/1.3.0/material.indigo-pink.min.css">
11+
<script defer src="https://code.getmdl.io/1.3.0/material.min.js"></script>
912
</head>
1013
<body>
1114
<noscript>

‎src/App.vue

Lines changed: 0 additions & 28 deletions
This file was deleted.

‎src/assets/logo.png

-6.69 KB
Binary file not shown.

‎src/components/HelloWorld.vue

Lines changed: 0 additions & 59 deletions
This file was deleted.

‎src/components/UsersList.spec.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// How would you test this component? Does it really need testing?
2+
describe('UsersList', () => {
3+
it('tests something', () => {
4+
//
5+
})
6+
})

‎src/components/UsersList.vue

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<template>
2+
<div class="UsersList mdl-list">
3+
<users-list-item
4+
v-for="user in users"
5+
:key="user.id"
6+
:user="user"
7+
@delete="$emit('user-delete', user)"
8+
/>
9+
</div>
10+
</template>
11+
12+
<script>
13+
import UsersListItem from './UsersListItem'
14+
15+
export default {
16+
components: {
17+
UsersListItem
18+
},
19+
props: {
20+
users: {
21+
type: Array,
22+
required: true
23+
}
24+
}
25+
}
26+
</script>

‎src/components/UsersListItem.spec.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// How would you test this component. Does it need testing?
2+
describe('UsersListItem', () => {
3+
it('tests something', () => {
4+
5+
})
6+
})

‎src/components/UsersListItem.vue

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<template>
2+
<div class="UsersListItem mdl-list__item mdl-list__item--two-line">
3+
<div class="mdl-list__item-primary-content">
4+
<i class="material-icons mdl-list__item-icon">person</i>
5+
<span>
6+
{{ user.name }} - <small>{{ user.email }}</small>
7+
</span>
8+
<span class="mdl-list__item-sub-title">
9+
{{ user.address.street }}
10+
</span>
11+
</div>
12+
<span class="mdl-list__item-secondary-content">
13+
<a
14+
class="mdl-list__item-secondary-action"
15+
@click="$emit('delete')"
16+
>
17+
<i class="material-icons">delete</i>
18+
</a>
19+
</span>
20+
</div>
21+
</template>
22+
23+
<script>
24+
export default {
25+
props: {
26+
user: {
27+
type: Object,
28+
required: true
29+
}
30+
}
31+
}
32+
</script>

‎src/main.js

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
1+
// The Vue build version to load with the `import` command
2+
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
13
import Vue from 'vue'
2-
import App from './App.vue'
4+
import { setupStore } from './store'
5+
6+
import Home from './pages/Home.vue'
37

48
Vue.config.productionTip = false
9+
/* eslint-disable no-new */
510

611
new Vue({
7-
render: h => h(App)
8-
}).$mount('#app')
12+
el: '#app',
13+
render: h => h(Home),
14+
store: setupStore(Vue)
15+
})

‎src/pages/Home.spec.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { createLocalVue, mount } from '@vue/test-utils'
2+
import Home from './Home'
3+
import users from '../store/modules/users'
4+
import Vuex from 'vuex'
5+
6+
let store
7+
const localVue = createLocalVue()
8+
localVue.use(Vuex)
9+
10+
function createWrapper () {
11+
return mount(Home, { localVue, store })
12+
}
13+
14+
describe('components', () => {
15+
beforeEach(() => {
16+
store = new Vuex.Store({
17+
modules: {
18+
users: users
19+
}
20+
})
21+
})
22+
23+
it('should fetch users', async () => {
24+
const wrapper = createWrapper()
25+
26+
expect(wrapper.findAll('.UsersListItem')).toHaveLength(0)
27+
wrapper.find('.mdl-button').trigger('click')
28+
// what next?
29+
})
30+
31+
it('should only fetch once', () => {
32+
const wrapper = createWrapper()
33+
34+
expect(wrapper.findAll('.UsersListItem')).toHaveLength(0)
35+
wrapper.find('.mdl-button').trigger('click')
36+
// what next?
37+
})
38+
39+
it('other?', () => {
40+
41+
})
42+
})

‎src/pages/Home.vue

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<template>
2+
<div class="mdl-layout mdl-js-layout">
3+
<div class="mdl-layout__content">
4+
<div class="mdl-grid">
5+
<div class="mdl-cell mdl-cell--middle">
6+
<button
7+
class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored"
8+
@click="fetchUsers"
9+
>
10+
Fetch Users Once
11+
</button>
12+
</div>
13+
14+
</div>
15+
<div class="mdl-grid">
16+
<div class="mdl-cell mdl-cell--12-col">
17+
<users-list :users="users" />
18+
</div>
19+
</div>
20+
</div>
21+
</div>
22+
</template>
23+
24+
<script>
25+
import UsersList from '@/components/UsersList'
26+
27+
export default {
28+
components: {
29+
UsersList
30+
},
31+
32+
computed: {
33+
users () {
34+
return this.$store.getters.users
35+
}
36+
},
37+
38+
methods: {
39+
fetchUsers () {
40+
this.$store.dispatch('fetchUsers', Date.now())
41+
},
42+
deleteUser () {
43+
// delete the user
44+
}
45+
}
46+
}
47+
</script>

‎src/store/index.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import Vuex from 'vuex'
2+
3+
import users from './modules/users'
4+
5+
let store
6+
7+
export function setupStore (Vue) {
8+
Vue.use(Vuex)
9+
store = new Vuex.Store({
10+
modules: {
11+
users: users
12+
}
13+
})
14+
return store
15+
}
16+
17+
export default store

‎src/store/modules/users.js

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import axios from 'axios'
2+
3+
const state = {
4+
users: [],
5+
fetchedAt: null,
6+
isDeleting: false
7+
}
8+
9+
const getters = {
10+
users: state => state.users,
11+
isDeleting: state => state.isDeleting
12+
}
13+
14+
const mutations = {
15+
SET_USERS (state, users) {
16+
console.log('Old users', state.users, 'New users', users)
17+
state.users = users
18+
},
19+
SET_LAST_FETCHED (state, fetchedAt) {
20+
state.fetchedAt = fetchedAt
21+
}
22+
}
23+
24+
const actions = {
25+
fetchUsers ({ state, commit }, fetchAt) {
26+
if (state.users.length) return
27+
return axios
28+
.get('https://jsonplaceholder.typicode.com/users')
29+
.then(({ data }) => {
30+
commit('SET_USERS', data)
31+
commit('SET_LAST_FETCHED', fetchAt)
32+
})
33+
},
34+
35+
deleteUser ({ state, commit }, user) {
36+
// How would you remove a user?
37+
// make call to api
38+
// update local data
39+
console.log('user deleted')
40+
},
41+
42+
updateUser () {
43+
// make call to api
44+
// update local user data
45+
console.log('user updated')
46+
}
47+
}
48+
49+
export default {
50+
state,
51+
getters,
52+
mutations,
53+
actions
54+
}

‎src/store/modules/users.spec.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import users from './users'
2+
import Vuex from 'vuex'
3+
import { createLocalVue } from '@vue/test-utils'
4+
5+
const userResponse = [{
6+
id: 1,
7+
name: 'User'
8+
}, {
9+
id: 2,
10+
name: 'User 2'
11+
}]
12+
13+
let store
14+
const localVue = createLocalVue()
15+
localVue.use(Vuex)
16+
17+
describe('users', () => {
18+
beforeEach(() => {
19+
store = new Vuex.Store(users)
20+
})
21+
it('should save the last time something was fetched', async () => {
22+
expect(store.state.users).toHaveLength(0)
23+
await store.dispatch('fetchUsers', 1000)
24+
expect(store.state.users).toEqual(userResponse)
25+
expect(store.state.fetchedAt).toEqual(1000)
26+
})
27+
28+
it('should not fetch users 2 times', async () => {
29+
expect(store.state.users).toHaveLength(0)
30+
await store.dispatch('fetchUsers', Date.now())
31+
await store.dispatch('fetchUsers', Date.now())
32+
})
33+
34+
it('should delete a user', () => {
35+
36+
})
37+
38+
// ...more tests
39+
})

‎tests/unit/example.spec.js

Lines changed: 0 additions & 12 deletions
This file was deleted.

‎yarn.lock

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1882,6 +1882,13 @@ aws4@^1.8.0:
18821882
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.9.1.tgz#7e33d8f7d449b3f673cd72deb9abdc552dbe528e"
18831883
integrity sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==
18841884

1885+
axios@^0.19.2:
1886+
version "0.19.2"
1887+
resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.2.tgz#3ea36c5d8818d0d5f8a8a97a6d36b86cdc00cb27"
1888+
integrity sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==
1889+
dependencies:
1890+
follow-redirects "1.5.10"
1891+
18851892
babel-code-frame@^6.26.0:
18861893
version "6.26.0"
18871894
resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b"
@@ -3235,6 +3242,13 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9:
32353242
dependencies:
32363243
ms "2.0.0"
32373244

3245+
debug@=3.1.0:
3246+
version "3.1.0"
3247+
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
3248+
integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
3249+
dependencies:
3250+
ms "2.0.0"
3251+
32383252
debug@^3.0.0, debug@^3.1.1, debug@^3.2.5:
32393253
version "3.2.6"
32403254
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b"
@@ -4352,6 +4366,13 @@ flush-write-stream@^1.0.0:
43524366
inherits "^2.0.3"
43534367
readable-stream "^2.3.6"
43544368

4369+
follow-redirects@1.5.10:
4370+
version "1.5.10"
4371+
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a"
4372+
integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==
4373+
dependencies:
4374+
debug "=3.1.0"
4375+
43554376
follow-redirects@^1.0.0:
43564377
version "1.10.0"
43574378
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.10.0.tgz#01f5263aee921c6a54fb91667f08f4155ce169eb"
@@ -9708,6 +9729,11 @@ vue@^2.6.11:
97089729
resolved "https://registry.yarnpkg.com/vue/-/vue-2.6.11.tgz#76594d877d4b12234406e84e35275c6d514125c5"
97099730
integrity sha512-VfPwgcGABbGAue9+sfrD4PuwFar7gPb1yl1UK1MwXoQPAw0BKSqWfoYCT/ThFrdEVWoI51dBuyCoiNU9bZDZxQ==
97109731

9732+
vuex@^3.1.3:
9733+
version "3.1.3"
9734+
resolved "https://registry.yarnpkg.com/vuex/-/vuex-3.1.3.tgz#f2ad73e3fb73691698b38c93f66e58e267947180"
9735+
integrity sha512-k8vZqNMSNMgKelVZAPYw5MNb2xWSmVgCKtYKAptvm9YtZiOXnRXFWu//Y9zQNORTrm3dNj1n/WaZZI26tIX6Mw==
9736+
97119737
w3c-hr-time@^1.0.1:
97129738
version "1.0.2"
97139739
resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd"

0 commit comments

Comments
 (0)
Please sign in to comment.