vue-carousel
Version:
A flexible, responsive, touch-friendly carousel for Vue.js
939 lines (770 loc) • 25.6 kB
JavaScript
/* eslint-disable */
import { mount, shallowMount } from '@vue/test-utils';
const Carousel = require('../../../src/Carousel.vue');
const Slide = require('../../../src/Slide.vue');
describe('Carousel component', () => {
describe('Default mounting properties', () => {
it('should mount successfully', () => {
const wrapper = mount(Carousel);
expect(wrapper.vm._isMounted).toBeTruthy();
expect(wrapper).toMatchSnapshot();
});
it('should unmount successfully', () => {
const wrapper = mount(Carousel);
const carouselInstance = wrapper.vm;
carouselInstance.$destroy();
expect(carouselInstance._isDestroyed).toBeTruthy();
expect(wrapper).toMatchSnapshot();
});
it('should be unable to advance backward by default', () => {
const wrapper = mount(Carousel);
expect(wrapper.vm.canAdvanceBackward).toBeFalsy();
expect(wrapper).toMatchSnapshot();
});
it('should be unable to advance forward by default (no slides added)', () => {
const wrapper = mount(Carousel);
expect(wrapper.vm.canAdvanceForward).toBeFalsy();
expect(wrapper).toMatchSnapshot();
});
it('should apply default carousel width when element has 0 width', () => {
const wrapper = mount(Carousel);
expect(wrapper.vm.carouselWidth).toBe(0);
expect(wrapper).toMatchSnapshot();
});
it('should register 0 slides when 0 slides are added to the slots', () => {
const wrapper = mount(Carousel);
expect(wrapper.vm.slideCount).toBe(0);
expect(wrapper).toMatchSnapshot();
});
it('should register 3 slides when 3 slides are added to the slots', done => {
const wrapper = mount(Carousel, {
slots: {
default: [Slide, Slide, Slide]
}
});
expect(wrapper.vm.slideCount).toBe(3);
wrapper.vm.$nextTick(() => {
expect(wrapper).toMatchSnapshot();
done();
});
});
});
describe('Adjustable height easing', () => {
it('should not set adjustable height transition easing', done => {
const wrapper = mount(Carousel, {
propsData: {
adjustableHeight: false,
adjustableHeightEasing: 'linear',
speed: 0
}
});
expect(wrapper.vm.transitionStyle).toBe('0s ease transform');
wrapper.vm.$nextTick(() => {
expect(wrapper).toMatchSnapshot();
done();
});
});
it('should set adjustable height transition easing', done => {
const wrapper = mount(Carousel, {
propsData: {
adjustableHeight: true,
adjustableHeightEasing: 'linear',
speed: 0
}
});
expect(wrapper.vm.transitionStyle).toBe('0s ease transform, height 0s linear');
wrapper.vm.$nextTick(() => {
expect(wrapper).toMatchSnapshot();
done();
});
});
});
describe('Autoplay functionality', () => {
it('should disable autoplay by default', () => {
const wrapper = shallowMount(Carousel);
expect(wrapper.vm.autoplay).toBe(false);
});
it('should set the autoplay direction to forward by default', () => {
const wrapper = shallowMount(Carousel);
expect(wrapper.vm.autoplayDirection).toBe('forward');
});
it('should set the autoplay hover pause to true by default', () => {
const wrapper = shallowMount(Carousel);
expect(wrapper.vm.autoplayHoverPause).toBe(true);
});
it('should set the autoplay timeout to 2000 by default', () => {
const wrapper = shallowMount(Carousel);
expect(wrapper.vm.autoplayTimeout).toBe(2000);
});
it('should begin autoplaying when option specified', done => {
const wrapper = mount(Carousel, {
propsData: {
perPage: 1,
autoplay: true,
autoplayHoverPause: true
},
slots: {
default: [Slide, Slide]
}
});
expect(wrapper.vm.autoplayInterval).toBeDefined();
wrapper.vm.pauseAutoplay();
expect(wrapper.vm.autoplayInterval).toBe(undefined);
wrapper.vm.$nextTick(() => {
expect(wrapper).toMatchSnapshot();
done();
});
});
it('should reset autoplay when switching slide without autoplayHoverPause', done => {
const wrapper = mount(Carousel, {
propsData: {
perPage: 1,
autoplay: true,
autoplayHoverPause: false
},
slots: {
default: [Slide, Slide]
}
});
const spy = jest.spyOn(wrapper.vm, 'restartAutoplay');
wrapper.vm.goToPage(2);
expect(wrapper.vm.restartAutoplay).toHaveBeenCalled();
spy.mockRestore();
wrapper.vm.$nextTick(() => {
expect(wrapper).toMatchSnapshot();
done();
});
});
it('should not reset autoplay when switching slide with autoplayHoverPause', done => {
const wrapper = mount(Carousel, {
propsData: {
perPage: 1,
autoplay: true,
autoplayHoverPause: true
},
slots: {
default: [Slide, Slide]
}
});
const spy = jest.spyOn(wrapper.vm, 'restartAutoplay');
wrapper.vm.goToPage(2);
expect(wrapper.vm.restartAutoplay).not.toHaveBeenCalled();
spy.mockRestore();
wrapper.vm.$nextTick(() => {
expect(wrapper).toMatchSnapshot();
done();
});
});
});
describe('Center mode', () => {
it('should not center slides when centerMode is not enabled by default', async () => {
const wrapper = shallowMount(Carousel, {
propsData: {
perPage: 2
},
slots: {
default: Slide
}
});
await wrapper.vm.$nextTick();
expect(wrapper.find('.VueCarousel-inner--center').exists()).toBe(false);
});
it('should center slides when there are less slides than can be displayed and centerMode is true', async () => {
const wrapper = shallowMount(Carousel, {
propsData: {
perPage: 2,
centerMode: true
},
slots: {
default: Slide
}
});
await wrapper.vm.$nextTick();
expect(wrapper.find('.VueCarousel-inner--center').exists()).toBe(true);
});
it('should not center images when there are more slides than can be displayed and centerMode is true', async () => {
const wrapper = shallowMount(Carousel, {
propsData: {
perPage: 1,
centerMode: true
},
slots: {
default: [Slide, Slide]
}
});
await wrapper.vm.$nextTick();
expect(wrapper.find('.VueCarousel-inner--center').exists()).toBe(false);
});
});
describe('Active slides class', () => {
it('should be present by default on the visible slides', done => {
const wrapper = mount(Carousel, {
slots: {
default: [Slide, Slide, Slide]
}
});
wrapper.vm.$nextTick(() => {
expect(wrapper.findAll('.VueCarousel-slide-active').length).toBe(2);
expect(wrapper).toMatchSnapshot();
done();
});
});
it('should be present on the appropriate number of slides when responsive param provided', done => {
const wrapper = mount(Carousel, {
propsData: {
perPageCustom: [[0, 3]]
},
slots: {
default: [Slide, Slide, Slide, Slide, Slide, Slide]
}
});
wrapper.vm.$nextTick(() => {
expect(wrapper.findAll('.VueCarousel-slide-active').length).toBe(3);
expect(wrapper).toMatchSnapshot();
done();
});
});
it('should be present on the appropriate number of slides when perPage is used', done => {
const wrapper = mount(Carousel, {
propsData: {
perPage: 1
},
slots: {
default: [Slide, Slide, Slide, Slide, Slide]
}
});
wrapper.vm.$nextTick(() => {
expect(wrapper.findAll('.VueCarousel-slide-active').length).toBe(1);
expect(wrapper).toMatchSnapshot();
done();
});
});
});
describe('Custom easing property', () => {
it('should set easing to ease by default', () => {
const wrapper = shallowMount(Carousel);
expect(wrapper.vm.transitionStyle).toMatch(/ease/);
});
it('should set easing to the custom value supplied', () => {
const wrapper = shallowMount(Carousel, {
propsData: {
easing: 'linear'
}
});
expect(wrapper.vm.transitionStyle).toMatch(/linear/);
});
});
describe('Loop functionality', () => {
it('should loop back to the start when loop is true and advance page non "backward" is called from the last page', done => {
const wrapper = mount(Carousel, {
propsData: {
perPage: 1,
loop: true
},
slots: {
default: [Slide, Slide]
}
});
wrapper.vm.$nextTick(() => {
wrapper.vm.goToPage(1);
wrapper.vm.advancePage();
expect(wrapper.vm.currentPage).toBe(0);
expect(wrapper).toMatchSnapshot();
done();
});
});
it('should loop to the end when loop is true and advance page "backward" is called from the first page', done => {
const wrapper = mount(Carousel, {
propsData: {
perPage: 1,
loop: true
},
slots: {
default: [Slide, Slide]
}
});
wrapper.vm.$nextTick(() => {
wrapper.vm.advancePage('backward');
expect(wrapper.vm.currentPage).toBe(1);
expect(wrapper).toMatchSnapshot();
done();
});
});
});
describe('Minimum swipe distance', () => {
it('should set minSwipeDistance to 8 by default', () => {
const wrapper = shallowMount(Carousel);
expect(wrapper.vm.minSwipeDistance).toBe(8);
});
it('should set minSwipeDistance to the custom value of 10', () => {
const wrapper = shallowMount(Carousel, {
propsData: {
minSwipeDistance: 10
}
});
expect(wrapper.vm.minSwipeDistance).toBe(10);
});
});
describe('Mouse drag', () => {
it('should set the mouseDrag to true by default', () => {
const wrapper = shallowMount(Carousel);
expect(wrapper.vm.mouseDrag).toBe(true);
});
it('should set the mouseDrag to false', () => {
const wrapper = shallowMount(Carousel, {
propsData: {
mouseDrag: false
}
});
expect(wrapper.vm.mouseDrag).toBe(false);
});
});
describe('Carousel navigation', () => {
it('should render the navigation component when navigation is enabled and navigation is required', async () => {
const wrapper = shallowMount(Carousel, {
propsData: {
navigationEnabled: true
},
slots: {
default: [Slide, Slide, Slide]
}
});
await wrapper.vm.$nextTick();
expect(wrapper.find('navigation-stub').exists()).toBe(true);
expect(wrapper).toMatchSnapshot();
});
it('should not render the navigation component when navigation is disabled', async () => {
const wrapper = shallowMount(Carousel, {
slots: {
default: [Slide, Slide, Slide]
}
});
await wrapper.vm.$nextTick();
expect(wrapper.find('navigation-stub').exists()).toBe(false);
expect(wrapper).toMatchSnapshot();
});
it('should navigate to slide 1', async () => {
const wrapper = shallowMount(Carousel, {
propsData: {
navigationEnabled: true
},
slots: {
default: [Slide, Slide, Slide]
}
});
wrapper.vm.carouselWidth = 1; // Set a width otherwise internal calculations will not make sense
await wrapper.vm.$nextTick();
expect(wrapper.vm.currentPage).toBe(0);
wrapper.find('navigation-stub').vm.$emit('navigationclick');
expect(wrapper.vm.currentPage).toBe(1);
});
it('should navigate to slide 2 even when navigation is not enabled', async () => {
const wrapper = shallowMount(Carousel, {
propsData: {
navigateTo: 2
},
slots: {
default: [Slide, Slide, Slide]
}
});
await wrapper.vm.$nextTick();
expect(wrapper.vm.currentPage).toBe(2);
});
});
describe('Carousel pagination', () => {
it('should render the pagination component when pagination is enabled', () => {
const wrapper = mount(Carousel);
expect(wrapper.find({ name: 'pagination' }).exists()).toBe(true);
});
it('should not render the pagination component when pagination is disabled', () => {
const wrapper = mount(Carousel, { propsData: { paginationEnabled: false } });
expect(wrapper.find({ name: 'pagination' }).exists()).toBe(false);
});
it('should move the carousel to page 1', async () => {
const wrapper = shallowMount(Carousel, {
slots: {
default: [Slide, Slide, Slide]
}
});
wrapper.vm.carouselWidth = 1; // Set a width otherwise internal calculations will not make sense
await wrapper.vm.$nextTick();
expect(wrapper.vm.currentPage).toBe(0);
wrapper.find('pagination-stub').vm.$emit('paginationclick', 1);
expect(wrapper.vm.currentPage).toBe(1);
});
});
describe('Carousel slides per page', () => {
it('should apply custom slides per page when responsive param provided', () => {
const wrapper = mount(Carousel, {
propsData: {
perPageCustom: [[0, 20]]
}
});
expect(wrapper.vm.currentPerPage).toBe(20);
expect(wrapper).toMatchSnapshot();
});
it('should fall back to default slides per page when no responsive param provided', done => {
const wrapper = mount(Carousel, {
propsData: {
scrollPerPage: true,
perPageCustom: [[9999, 20]]
},
slots: {
default: [Slide, Slide, Slide]
}
});
expect(wrapper.vm.currentPerPage).toBe(2);
expect(wrapper.vm.pageCount).toBe(2);
wrapper.vm.$nextTick(() => {
expect(wrapper).toMatchSnapshot();
done();
});
});
it('should have 2 slides on the current page by default', () => {
const wrapper = shallowMount(Carousel);
expect(wrapper.vm.perPage).toBe(2);
});
it('should have 3 slides on the current page when perPage is set to 3', () => {
const wrapper = shallowMount(Carousel, {
propsData: {
perPage: 3
}
});
expect(wrapper.vm.perPage).toBe(3);
});
it('should have 3 pages when number of slides is 6', () => {
const wrapper = shallowMount(Carousel, {
slots: {
default: [Slide, Slide, Slide, Slide, Slide, Slide]
}
});
expect(wrapper.vm.pageCount).toBe(3);
});
it('should only have one page when number of slides is less than slides per page', () => {
const wrapper = shallowMount(Carousel, {
propsData: {
perPage: 3
},
slots: {
default: [Slide, Slide, Slide]
}
});
expect(wrapper.vm.pageCount).toBe(1);
});
});
describe('Carousel resistance co-efficient pull effect', () => {
it('should have the resistanceCoef set to 20 by default', () => {
const wrapper = shallowMount(Carousel);
expect(wrapper.vm.resistanceCoef).toBe(20);
});
it('should set the resistanceCoef to 30', () => {
const wrapper = shallowMount(Carousel, {
propsData: {
resistanceCoef: 30
},
slots: {
default: [Slide, Slide, Slide]
}
});
expect(wrapper.vm.resistanceCoef).toBe(30);
});
});
describe('Scrolling per page', () => {
it('should have scroll per page set to true by default', () => {
const wrapper = shallowMount(Carousel);
expect(wrapper.vm.scrollPerPage).toBe(true);
});
it('should go to second slide when we have odd number of slides and recompute carousel width', done => {
const wrapper = mount(Carousel, {
propsData: {
scrollPerPage: true,
perPage: 2
},
slots: {
default: [Slide, Slide, Slide, Slide, Slide]
}
});
wrapper.vm.carouselWidth = 500;
wrapper.vm.$nextTick(() => {
wrapper.vm.goToPage(1);
wrapper.vm.computeCarouselWidth();
expect(wrapper.vm.currentPage).toBe(1);
done();
});
});
it('should advanced the page by only one slide (half the carousel width) when scroll per page is false', async () => {
const wrapper = shallowMount(Carousel, {
propsData: {
scrollPerPage: false,
navigationEnabled: true
},
slots: {
default: [Slide, Slide, Slide]
}
});
wrapper.vm.carouselWidth = 1; // Set a width otherwise internal calculations will not make sense
await wrapper.vm.$nextTick();
expect(wrapper.vm.offset).toBe(0);
wrapper.find('navigation-stub').vm.$emit('navigationclick');
expect(wrapper.vm.offset).toBe(0.5);
});
});
describe('Space padding', () => {
it('should have 0 space padding by default', () => {
const wrapper = shallowMount(Carousel);
expect(wrapper.vm.spacePadding).toBe(0);
});
it('should have 0 space padding maximum offset factor by default', () => {
const wrapper = shallowMount(Carousel);
expect(wrapper.vm.spacePaddingMaxOffsetFactor).toBe(0);
});
it('should have 10 space padding', () => {
const wrapper = shallowMount(Carousel, {
propsData: {
spacePadding: 10
}
});
expect(wrapper.vm.spacePadding).toBe(10);
});
it('should have 10 space padding maximum offset factor by default', () => {
const wrapper = shallowMount(Carousel, {
propsData: {
spacePaddingMaxOffsetFactor: 10
}
});
expect(wrapper.vm.spacePaddingMaxOffsetFactor).toBe(10);
});
});
describe('Speed', () => {
it('should have a speed of 500 by default', () => {
const wrapper = shallowMount(Carousel);
expect(wrapper.vm.speed).toBe(500);
});
it('should have a speed of 600', () => {
const wrapper = shallowMount(Carousel, {
propsData: {
speed: 600
}
});
expect(wrapper.vm.speed).toBe(600);
});
});
describe('Tag name', () => {
it('should only count slides matching the default tagName of slide', async () => {
const CustomSlide = {
extends: Slide,
name: 'CustomSlide',
};
const wrapper = mount(Carousel, {
slots: {
default: [CustomSlide, CustomSlide, Slide]
}
});
expect(wrapper.vm.tagName).toBe('slide');
expect(wrapper.vm.slideCount).toBe(1);
});
it('should only count slides matching tagName', done => {
const CustomSlide = {
extends: Slide,
name: 'CustomSlide',
};
const wrapper = mount(Carousel, {
propsData: {
tagName: 'CustomSlide'
},
slots: {
default: [CustomSlide, CustomSlide, Slide]
}
});
expect(wrapper.vm.tagName).toBe('CustomSlide');
expect(wrapper.vm.slideCount).toBe(2);
wrapper.vm.$nextTick(() => {
expect(wrapper).toMatchSnapshot();
done();
});
});
});
describe('v-model with value prop', () => {
it('should set currentPage to 1', async () => {
const wrapper = shallowMount(Carousel, {
propsData: {
value: 0
},
slots: {
default: [Slide, Slide, Slide]
}
});
wrapper.vm.carouselWidth = 1; // Set a width otherwise internal calculations will not make sense
await wrapper.vm.$nextTick();
expect(wrapper.emitted().input).toBeUndefined();
expect(wrapper.vm.currentPage).toBe(0);
wrapper.setProps({ value: 1 });
await wrapper.vm.$nextTick();
expect(wrapper.emitted().input[0][0]).toBe(1);
expect(wrapper.vm.currentPage).toBe(1);
});
it('should not change the current page when selecting the same page', async () => {
const wrapper = shallowMount(Carousel, {
propsData: {
value: 0
},
slots: {
default: [Slide, Slide, Slide]
}
});
wrapper.vm.carouselWidth = 1; // Set a width otherwise internal calculations will not make sense
await wrapper.vm.$nextTick();
expect(wrapper.emitted().input).toBeUndefined();
expect(wrapper.vm.currentPage).toBe(0);
wrapper.setProps({ value: 0 });
await wrapper.vm.$nextTick();
expect(wrapper.emitted().input).toBeUndefined();
expect(wrapper.vm.currentPage).toBe(0);
});
it('should not change the current page when value is negative', async () => {
const wrapper = shallowMount(Carousel, {
propsData: {
value: 0
},
slots: {
default: [Slide, Slide, Slide]
}
});
wrapper.vm.carouselWidth = 1; // Set a width otherwise internal calculations will not make sense
await wrapper.vm.$nextTick();
expect(wrapper.emitted().input).toBeUndefined();
expect(wrapper.vm.currentPage).toBe(0);
wrapper.setProps({ value: -1 });
await wrapper.vm.$nextTick();
expect(wrapper.emitted().input).toBeUndefined();
expect(wrapper.vm.currentPage).toBe(0);
});
it('should not change the current page when value is greater than pageCount', async () => {
const wrapper = shallowMount(Carousel, {
propsData: {
value: 0
},
slots: {
default: [Slide, Slide, Slide]
}
});
wrapper.vm.carouselWidth = 1; // Set a width otherwise internal calculations will not make sense
await wrapper.vm.$nextTick();
expect(wrapper.emitted().input).toBeUndefined();
expect(wrapper.vm.currentPage).toBe(0);
wrapper.setProps({ value: 100 });
await wrapper.vm.$nextTick();
expect(wrapper.emitted().input).toBeUndefined();
expect(wrapper.vm.currentPage).toBe(0);
});
});
describe('Events', () => {
it('should emit a pageChange event with the page number on page change', async () => {
const wrapper = shallowMount(Carousel, {
propsData: {
navigateTo: 2
},
slots: {
default: [Slide, Slide, Slide]
}
});
await wrapper.vm.$nextTick();
expect(wrapper.emitted().pageChange[0][0]).toBe(2);
});
it('should emit a transitionEnd event on transition end', async () => {
const wrapper = shallowMount(Carousel);
wrapper.vm.handleTransitionEnd();
expect(wrapper.emitted().transitionEnd).toBeDefined();
});
});
it('should decrease current page number by 1 when advance page backward is called', done => {
const wrapper = mount(Carousel, {
propsData: {
perPage: 1
},
slots: {
default: [Slide, Slide]
}
});
wrapper.vm.$nextTick(() => {
wrapper.vm.goToPage(2);
wrapper.vm.advancePage('backward');
expect(wrapper.vm.currentPage).toBe(1);
expect(wrapper).toMatchSnapshot();
done();
});
});
it('should increase current page number by 1 when advance page is called', done => {
const wrapper = mount(Carousel, {
propsData: {
perPage: 1
},
slots: {
default: [Slide, Slide, Slide, Slide]
}
});
wrapper.vm.$nextTick(() => {
wrapper.vm.goToPage(1);
wrapper.vm.advancePage();
expect(wrapper.vm.currentPage).toBe(1);
expect(wrapper).toMatchSnapshot();
done();
});
});
it('should increase current page number by 1 when advance page is called with a non "backward" argument', done => {
const wrapper = mount(Carousel, {
propsData: {
perPage: 1
},
slots: {
default: [Slide, Slide, Slide, Slide]
}
});
wrapper.vm.$nextTick(() => {
wrapper.vm.goToPage(1);
wrapper.vm.advancePage('something');
expect(wrapper.vm.currentPage).toBe(1);
expect(wrapper).toMatchSnapshot();
done();
});
});
it('should decrease current slide number by 1 when advance slide backward is called', done => {
const wrapper = mount(Carousel, {
propsData: {
perPage: 1,
scrollPerPage: false
},
slots: {
default: [Slide, Slide, Slide, Slide]
}
});
wrapper.vm.$nextTick(() => {
wrapper.vm.goToPage(2);
wrapper.vm.advancePage('backward');
expect(wrapper.vm.currentPage).toBe(1);
expect(wrapper).toMatchSnapshot();
done();
});
});
it('should set carousel height to slide height', done => {
const wrapper = mount(Carousel, {
propsData: {
adjustableHeight: true,
perPage: 1,
speed: 0
},
slots: {
default: [Slide, Slide, Slide]
},
sync: false
});
// Force the slide to return a specific height
Object.defineProperty(wrapper.vm.$children[2].$el, 'clientHeight', { value: 200 });
wrapper.vm.$nextTick(() => {
wrapper.vm.computeCarouselHeight();
expect(wrapper.vm.currentHeight).toBe('200px');
expect(wrapper).toMatchSnapshot();
done();
});
});
});