Created
January 18, 2018 20:16
-
-
Save kleinjm/47d83f5de4ff39d779b26c96f3d004f6 to your computer and use it in GitHub Desktop.
Test components and examples for VueJS L&L
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { mount, shallow, createLocalVue } from 'vue-test-utils'; | |
import VueRouter from 'vue-router'; | |
import { BASE_TRANSLATE } from '~src/store/constants'; | |
import Vuelidate from 'vuelidate'; | |
import createStore from '~src/store'; | |
const VUE_UTIL_METHODS = { shallow, mount }; | |
// Setup an isolated component wrapper with all our Vue bells and whistles | |
function buildDoxVue({ method, component, options = {} }) { | |
const store = createStore(); | |
const localVue = createLocalVue(); | |
component.apollo = undefined; | |
localVue.use(Vuelidate); | |
if (options.router) { | |
localVue.use(VueRouter); | |
} | |
localVue.prototype.$translate = store.getters[BASE_TRANSLATE]; | |
return VUE_UTIL_METHODS[method](component, { | |
localVue, | |
store, | |
...options, | |
}); | |
} | |
export function mountDoxVue(component, options) { | |
return buildDoxVue({ method: 'mount', component, options }); | |
} | |
export function shallowDoxVue(component, options) { | |
return buildDoxVue({ method: 'shallow', component, options }); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { shallow } from 'vue-test-utils'; | |
import MyComponent from '~src/packages/profiles/components/MyComponent1.vue'; | |
describe('MyComponent', () => { | |
describe('rendering items', () => { | |
it('renders all items in the list', () => { | |
const wrapper = shallow(MyComponent, { | |
propsData: { | |
users: [ | |
{ id: 1, name: 'First' }, | |
{ id: 2, name: 'Second' }, | |
{ id: 3, name: 'Third' }, | |
], | |
}, | |
}); | |
expect(wrapper.text()).to.include('First'); | |
expect(wrapper.text()).to.include('Second'); | |
expect(wrapper.text()).to.include('Third'); | |
}); | |
}); | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<template> | |
<ul> | |
<li v-for="user in users" | |
:key="user.id" | |
> | |
{{ user.name }} | |
</li> | |
</ul> | |
</template> | |
<script> | |
export default { | |
name: 'MyComponent', | |
props: { | |
users: Array, | |
}, | |
} | |
</script> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { shallow } from 'vue-test-utils'; | |
import MyComponent from '~src/packages/profiles/components/MyComponent2.vue'; | |
describe('MyComponent', () => { | |
const users = Object.freeze([ | |
{ id: 1, name: 'First' }, | |
{ id: 2, name: 'Second' }, | |
{ id: 3, name: 'Third' }, | |
]); | |
describe('rendering items', () => { | |
it('renders all items in the list', () => { | |
const wrapper = shallow(MyComponent, { | |
propsData: { | |
users, | |
profile: { admin: true }, | |
}, | |
}); | |
expect(wrapper.findAll('[data-test-user-item]').length).to.eq(3); | |
}); | |
it('does not render for non-admins', () => { | |
const wrapper = shallow(MyComponent, { propsData: { users } }); | |
// Empty wrappers render an empty comment <!----> | |
// The isEmpty method comes from vue-test-utils | |
expect(wrapper.isEmpty()).to.be.true; | |
}); | |
}); | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<template> | |
<ul v-if="isAdmin"> | |
<li v-for="user in users" | |
:key="user.id" | |
data-test-user-item | |
> | |
{{ user.name }} | |
</li> | |
</ul> | |
</template> | |
<script> | |
import _get from 'lodash/get'; | |
export default { | |
name: 'MyComponent', | |
props: { | |
users: Array, | |
profile: Object, | |
}, | |
computed: { | |
isAdmin() { | |
return _get(this.profile, 'admin', false); | |
}, | |
}, | |
} | |
</script> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { mount } from 'vue-test-utils'; | |
import MyComponent from '~src/packages/profiles/components/MyComponent3.vue'; | |
describe('MyComponent', () => { | |
const users = Object.freeze([ | |
{ id: 1, name: 'First' }, | |
{ id: 2, name: 'Second' }, | |
{ id: 3, name: 'Third' }, | |
]); | |
describe('rendering items', () => { | |
it('renders all items in the list', () => { | |
const wrapper = mount(MyComponent, { | |
propsData: { | |
users, | |
profile: { admin: true }, | |
}, | |
}); | |
expect(wrapper.findAll('[data-test-user-item]').length).to.eq(3); | |
}); | |
}); | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<template> | |
<ul v-if="isAdmin"> | |
<MyListItem v-for="user in users" | |
:key="user.id" | |
:user="user" | |
> | |
</MyListItem> | |
</ul> | |
</template> | |
<script> | |
import _get from 'lodash/get'; | |
import MyListItem from './MyListItem.vue'; | |
export default { | |
name: 'MyComponent', | |
components: { MyListItem }, | |
props: { | |
users: Array, | |
profile: Object, | |
}, | |
computed: { | |
isAdmin() { | |
return _get(this.profile, 'admin', false); | |
}, | |
}, | |
} | |
</script> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { mountDoxVue } from '~test/util/doxVue'; | |
import MyComponent from '~src/packages/profiles/components/MyComponent4.vue'; | |
describe('MyComponent', () => { | |
const users = Object.freeze([ | |
{ id: 1, name: 'First' }, | |
{ id: 2, name: 'Second' }, | |
{ id: 3, name: 'Third' }, | |
]); | |
describe('rendering items', () => { | |
it('renders all items in the list', () => { | |
const wrapper = mountDoxVue(MyComponent, { | |
data: { | |
users, | |
}, | |
}); | |
expect(wrapper.findAll('[data-test-user-item]').length).to.eq(3); | |
}); | |
}); | |
describe('toggleVueProfiles', () => { | |
it('displays the flash on success', async () => { | |
const performToggleFeatureMutation = sinon | |
.stub() | |
.resolves({ success: true }); | |
const wrapper = mountDoxVue(MyComponent, { | |
methods: { performToggleFeatureMutation }, | |
}); | |
wrapper.find('[data-test-vue-profiles-btn]').trigger('click'); | |
await wrapper.vm.$nextTick(); | |
expect(performToggleFeatureMutation.called).to.be.true; | |
expect(wrapper.html()).to.include('data-test-flash-message'); | |
}); | |
}); | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<template> | |
<div> | |
<div class="flash" | |
v-if="updatedSuccessfully" | |
data-test-flash-message | |
> | |
Vue profiles have been successfully turned on for all users | |
</div> | |
<ul> | |
<MyListItem v-for="user in users" | |
:key="user.id" | |
:user="user" | |
> | |
</MyListItem> | |
</ul> | |
<button @click="toggleVueProfiles" | |
data-test-vue-profiles-btn | |
> | |
Toggle Vue Profiles | |
</button> | |
</div> | |
</template> | |
<script> | |
import MyListItem from './MyListItem.vue'; | |
import gql from 'graphql-tag'; | |
import toggleFeatureMutation from './toggleFeatureMutation'; | |
import invariant from '~src/lib/invariant'; | |
export default { | |
name: 'MyComponent', | |
components: { MyListItem }, | |
data() { | |
return { | |
users: [], | |
updatedSuccessfully: false, | |
}; | |
}, | |
computed: { | |
userIds() { | |
return _map(this.users, 'id'); | |
}, | |
}, | |
methods: { | |
performToggleFeatureMutation() { | |
return toggleFeatureMutation({ | |
apollo: this.$apollo, | |
featureName: 'vue-profile', | |
userIds: this.userIds, | |
refetchQueries: this.refetchQueries, | |
}); | |
}, | |
toggleVueProfiles() { | |
return this.performToggleFeatureMutation().then(response => { | |
if(response.success) this.updatedSuccessfully = true; | |
}).catch(error => { | |
this.updatedSuccessfully = false; | |
invariant(false, error); | |
}); | |
}, | |
}, | |
apollo: { | |
users: { | |
query: gql`query users { | |
users { | |
id | |
name | |
} | |
}`, | |
}, | |
}, | |
} | |
</script> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { mount } from 'vue-test-utils'; | |
import MyComponent from '~src/packages/profiles/components/MyComponent5.vue'; | |
describe('MyComponent', () => { | |
const users = [{ id: 1, name: 'First' }]; | |
describe('flash message', () => { | |
it('shows the flash when clicking delete all button', () => { | |
const wrapper = mount(MyComponent, { | |
propsData: { users, profile: { admin: true } }, | |
}); | |
wrapper.find('[data-test-delete-all-btn]').trigger('click'); | |
expect(wrapper.find('[data-test-flash-message]')).to.exist; | |
// OR test the whole DOM | |
expect(wrapper.html()).to.contain('data-test-flash-message'); | |
}); | |
}); | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<template> | |
<div v-if="isAdmin"> | |
<div class="flash" | |
v-if="showFlashMessage" | |
data-test-flash-message | |
> | |
Are you sure you want to delete all users? You may get fired. | |
<button class="why-do-we-have-this-button"> | |
Yes, I'm outta here | |
</button> | |
<button class="they-better-click-this-one"> | |
No, I want to keep the users and my job | |
</button> | |
</div> | |
<ul> | |
<MyListItem v-for="user in users" | |
:key="user.id" | |
:user="user" | |
> | |
</MyListItem> | |
</ul> | |
<button class="super-danger-btn" | |
@click="deleteAllUsers" | |
data-test-delete-all-btn | |
> | |
Delete all users | |
</button> | |
</div> | |
</template> | |
<script> | |
import _get from 'lodash/get'; | |
import MyListItem from './MyListItem.vue'; | |
export default { | |
name: 'MyComponent', | |
components: { MyListItem }, | |
props: { | |
users: Array, | |
profile: Object, | |
}, | |
data() { | |
return { showFlashMessage: false }; | |
}, | |
computed: { | |
isAdmin() { | |
return _get(this.profile, 'admin', false); | |
}, | |
}, | |
methods: { | |
deleteAllUsers() { | |
this.showFlashMessage = true; | |
}, | |
}, | |
} | |
</script> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { mount } from 'vue-test-utils'; | |
import MyComponent from '~src/packages/profiles/components/MyComponent6.vue'; | |
describe('MyComponent', () => { | |
const users = Object.freeze([ | |
{ id: 1, name: 'First' }, | |
{ id: 2, name: 'Second' }, | |
{ id: 3, name: 'Third' }, | |
]); | |
let $router = []; | |
afterEach(() => { | |
$router = []; | |
}); | |
describe('navigation', () => { | |
it('goes to the profile page', () => { | |
const profileUUID = 'abc123'; | |
const wrapper = mount(MyComponent, { | |
propsData: { | |
users, | |
profile: { uuid: profileUUID, admin: true }, | |
}, | |
mocks: { $router }, | |
}); | |
wrapper.find('[data-test-profile-btn]').trigger('click'); | |
expect($router[0].name).to.eq('profiles-index'); | |
expect($router[0].params.profileUUID).to.eq(profileUUID); | |
}); | |
}); | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<template> | |
<div v-if="isAdmin"> | |
<ul> | |
<MyListItem v-for="user in users" | |
:key="user.id" | |
:user="user" | |
> | |
</MyListItem> | |
</ul> | |
<button @click="goToProfile" | |
data-test-profile-btn | |
> | |
Profile | |
</button> | |
</div> | |
</template> | |
<script> | |
import _get from 'lodash/get'; | |
import MyListItem from './MyListItem.vue'; | |
export default { | |
name: 'MyComponent', | |
components: { MyListItem }, | |
props: { | |
users: Array, | |
profile: Object, | |
}, | |
computed: { | |
isAdmin() { | |
return _get(this.profile, 'admin', false); | |
}, | |
profileUUID() { | |
return _get(this.profile, 'uuid', ''); | |
}, | |
}, | |
methods: { | |
goToProfile() { | |
this.$router.push({ | |
name: 'profiles-index', | |
params: { profileUUID: this.profileUUID }, | |
}); | |
}, | |
}, | |
} | |
</script> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { mountDoxVue } from '~test/util/doxVue'; | |
import MyComponent from '~src/packages/profiles/components/MyComponent7.vue'; | |
describe('MyComponent', () => { | |
const users = Object.freeze([{ id: 1, name: 'First' }]); | |
it('triggers a flash message', async () => { | |
const wrapper = mountDoxVue(MyComponent, { propsData: { users } }); | |
wrapper.find('[data-test-flash-btn]').trigger('click'); | |
await wrapper.vm.$nextTick(); | |
const message = wrapper.vm.$translate('MyComponent7.flashMessage'); | |
expect(wrapper.vm.$store.state.BASE.flashMessages[0].message).to.eq( | |
message | |
); | |
}); | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<template> | |
<div> | |
<ul> | |
<MyListItem v-for="user in users" | |
:key="user.id" | |
:user="user" | |
> | |
</MyListItem> | |
</ul> | |
<button @click="showFlash" | |
data-test-flash-btn | |
> | |
Do something flash message worthy | |
</button> | |
</div> | |
</template> | |
<script> | |
import MyListItem from './MyListItem.vue'; | |
import { mapMutations } from 'vuex'; | |
import { BASE_ADD_FLASH_MESSAGE } from '~src/packages/base/store.js'; | |
export default { | |
name: 'MyComponent', | |
components: { MyListItem }, | |
props: { | |
users: Array, | |
}, | |
methods: { | |
...mapMutations({ addFlashMessage: BASE_ADD_FLASH_MESSAGE }), | |
showFlash() { | |
this.performFlashDataQuery().then(response => { | |
if(response.success) { | |
this.addFlashMessage({ | |
message: this.$translate('MyComponent7.flashMessage'), | |
}); | |
} | |
}); | |
}, | |
performFlashDataQuery() { | |
return new Promise(resolve => { resolve({ success: true }) }); | |
}, | |
}, | |
} | |
</script> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<template> | |
<p data-test-user-item> | |
{{ user.name }} | |
</p> | |
</template> | |
<script> | |
export default { | |
name: 'MyListItem', | |
props: { | |
user: { | |
type: Object, | |
required: true, | |
}, | |
}, | |
} | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment