Skip to content

Commit 0095ea4

Browse files
committed
test: add more unit tests
1 parent 11a55b3 commit 0095ea4

File tree

3 files changed

+116
-56
lines changed

3 files changed

+116
-56
lines changed

src/components/VueImageKit.vue

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,10 @@ export default {
5757
}
5858
},
5959
data: () => ({
60-
imageKitPrefix: '',
61-
showCanvas: true
60+
imageKitPrefix: 'https://ik.imagekit.io',
61+
showCanvas: true,
62+
observer: null,
63+
timeOut: null
6264
}),
6365
computed: {
6466
dataUrl () {
@@ -97,48 +99,47 @@ export default {
9799
}
98100
},
99101
mounted () {
100-
// const protocol = document.location.protocol !== 'https:' ? 'http://' : 'https://'
101-
const protocol = 'https://'
102-
this.imageKitPrefix = `${protocol}ik.imagekit.io`
103-
104-
const { src, srcset, $el, getSrcset, imageKitPrefix, hash } = this
105-
let timeOut = null
106102
this.showCanvas = true
107103
108-
const observer = new IntersectionObserver(([entry]) => {
109-
const img = $el.querySelector('.vue-image-kit__img')
110-
const placeholder = $el.querySelector('.vue-image-kit__placeholder')
104+
this.observer = new IntersectionObserver(([entry]) => {
105+
this.triggerIntersection(entry)
106+
})
107+
this.observer.observe(this.$el)
108+
109+
this.$once('hook:beforeDestroy', () => {
110+
this.observer.disconnect()
111+
112+
if (this.timeOut) {
113+
clearTimeout(this.timeOut)
114+
}
115+
})
116+
},
117+
methods: {
118+
triggerIntersection(entry = {}) {
119+
const img = this.$el.querySelector('.vue-image-kit__img')
120+
const placeholder = this.$el.querySelector('.vue-image-kit__placeholder')
111121
112122
img.onload = function () {
113123
delete img.onload
114-
$el.classList.add('vue-image-kit--loaded')
124+
this.$el.classList.add('vue-image-kit--loaded')
115125
116126
if (placeholder) {
117-
timeOut = setTimeout(() => {
127+
this.timeOut = setTimeout(() => {
118128
placeholder.remove()
119129
}, 300)
120130
}
121131
}
122132
if (entry.isIntersecting) {
123133
this.showCanvas = false
124134
125-
if (srcset) {
126-
img.srcset = getSrcset
135+
if (this.srcset) {
136+
img.srcset = this.getSrcset
127137
}
128138
129-
img.src = `${imageKitPrefix}/${hash}/${src}`
130-
observer.disconnect()
139+
img.src = `${this.imageKitPrefix}/${this.hash}/${this.src}`
140+
this.observer.disconnect()
131141
}
132-
})
133-
observer.observe($el)
134-
135-
this.$once('hook:beforeDestroy', () => {
136-
observer.disconnect()
137-
138-
if (timeOut) {
139-
clearTimeout(timeOut)
140-
}
141-
})
142+
}
142143
}
143144
}
144145
</script>

tests/unit/__snapshots__/vue-image-kit.spec.js.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22

33
exports[`When I create the VueImageKit component should match snapshot 1`] = `
44
<div class="vue-image-kit">
5-
<!----> <img srcset="/6xhf1gnexgdgk/tr:w-320/lion_BllLvaqVn.jpg 320w, /6xhf1gnexgdgk/tr:w-480/lion_BllLvaqVn.jpg 480w, /6xhf1gnexgdgk/tr:w-800/lion_BllLvaqVn.jpg 800w" sizes="(max-width: 320px) 280px, (max-width: 480px) 440px, (max-width: 800px) 760px 1080px" src="" alt="" class="vue-image-kit__img"></div>
5+
<!----> <img srcset="https://ik.imagekit.io/6xhf1gnexgdgk/tr:w-320/lion_BllLvaqVn.jpg 320w, https://ik.imagekit.io/6xhf1gnexgdgk/tr:w-480/lion_BllLvaqVn.jpg 480w, https://ik.imagekit.io/6xhf1gnexgdgk/tr:w-800/lion_BllLvaqVn.jpg 800w" sizes="(max-width: 320px) 280px, (max-width: 480px) 440px, (max-width: 800px) 760px 1080px" src="" alt="" class="vue-image-kit__img"></div>
66
`;

tests/unit/vue-image-kit.spec.js

Lines changed: 87 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { mount } from '@vue/test-utils'
1+
import { mount, shallowMount, createLocalVue } from '@vue/test-utils'
22
import VueImageKit from '../../src/components/VueImageKit'
33
import 'jest-canvas-mock'
44

@@ -7,31 +7,30 @@ function setupIntersectionObserverMock({
77
unobserve = () => null,
88
} = {}) {
99
class IntersectionObserver {
10-
observe = observe;
11-
unobserve = unobserve;
10+
observe = observe
11+
unobserve = unobserve
12+
disconnect() {}
1213
}
1314
Object.defineProperty(
1415
window,
1516
'IntersectionObserver',
1617
{ writable: true, configurable: true, value: IntersectionObserver }
17-
);
18+
)
1819
Object.defineProperty(
1920
global,
2021
'IntersectionObserver',
2122
{ writable: true, configurable: true, value: IntersectionObserver }
22-
);
23+
)
2324
}
2425

2526
describe('When I create the VueImageKit component', () => {
2627
const item = { hash: '6xhf1gnexgdgk', src: 'lion_BllLvaqVn.jpg' }
2728

2829
beforeEach(() => {
29-
setupIntersectionObserverMock();
30+
setupIntersectionObserverMock()
3031
})
31-
const createComponent = (propsData = {}, slot) => {
32-
return mount(VueImageKit, {
33-
propsData
34-
})
32+
const createComponent = (propsData = {}) => {
33+
return shallowMount(VueImageKit, { propsData })
3534
}
3635

3736
it('should be a Vue instance', () => {
@@ -67,7 +66,6 @@ describe('When I create the VueImageKit component', () => {
6766
const sizes = wrapper.vm.$options.props.sizes
6867
expect(sizes.required).toBeFalsy()
6968
expect(sizes.type).toBe(Array)
70-
console.log(JSON.stringify(sizes.default))
7169
expect(JSON.stringify(sizes.default)).toBeFalsy()
7270
const defaultSize = wrapper.vm.$options.props.defaultSize
7371
expect(defaultSize.required).toBeFalsy()
@@ -123,23 +121,84 @@ describe('When I create the VueImageKit component', () => {
123121
expect(placeholder.attributes().style).toBe('background-color: rgb(255, 68, 0);') // #f40
124122
})
125123

126-
// ! Missing tests for props
127-
// srcset: {
128-
// type: Array,
129-
// default: () => [320, 480, 800]
130-
// },
131-
// sizes: {
132-
// type: Array,
133-
// default: () => []
134-
// },
135-
// defaultSize: {
136-
// type: Number,
137-
// default: 1080
138-
// },
139-
// customTransform: {
140-
// type: String,
141-
// default: ''
142-
// }
124+
it('should have different srcset from default', () => {
125+
const wrapper = createComponent({ ...item, srcset: [400, 600, 900] })
126+
const main = wrapper.find('.vue-image-kit > .vue-image-kit__img')
127+
expect(main.exists()).toBe(true)
128+
const expected = 'https://ik.imagekit.io/6xhf1gnexgdgk/tr:w-400/lion_BllLvaqVn.jpg 400w, https://ik.imagekit.io/6xhf1gnexgdgk/tr:w-600/lion_BllLvaqVn.jpg 600w, https://ik.imagekit.io/6xhf1gnexgdgk/tr:w-900/lion_BllLvaqVn.jpg 900w'
129+
expect(main.attributes().srcset).toBe(expected)
130+
})
131+
132+
it('should have different sizes from default', () => {
133+
const wrapper = createComponent({ ...item, srcset: [200, 250, 300] })
134+
const main = wrapper.find('.vue-image-kit > .vue-image-kit__img')
135+
expect(main.exists()).toBe(true)
136+
const expected = '(max-width: 200px) 160px, (max-width: 250px) 210px, (max-width: 300px) 260px 1080px'
137+
expect(main.attributes().sizes).toBe(expected)
138+
})
139+
140+
it('should have different default size', () => {
141+
const wrapper = createComponent({ ...item, defaultSize: 1366 })
142+
const main = wrapper.find('.vue-image-kit > .vue-image-kit__img')
143+
expect(main.exists()).toBe(true)
144+
expect(main.attributes().sizes).toContain('1366px')
145+
})
146+
147+
it('should have a custom transform', () => {
148+
// https://imagekit.io/features/advanced-image-manipulation-blur-rotate-crop-background-radius
149+
const customTransform = 'c-at_max,bl-1:r-20,bg-FFCFA1'
150+
const wrapper = createComponent({ ...item, customTransform })
151+
const main = wrapper.find('.vue-image-kit > .vue-image-kit__img')
152+
expect(main.exists()).toBe(true)
153+
expect(main.attributes().srcset).toContain(customTransform)
154+
})
155+
156+
it('should disconnect the observer on destroy', () => {
157+
const wrapper = createComponent({ ...item })
158+
expect(wrapper.vm.observer).toStrictEqual(new IntersectionObserver({ observe: () => jest.fn(), unobserve: () => jest.fn() }))
159+
wrapper.destroy()
160+
expect(wrapper.vm.observer).toStrictEqual(new IntersectionObserver({ observe: () => jest.fn(), unobserve: () => jest.fn() }))
161+
const disconnect = jest.fn()
162+
expect(JSON.stringify(wrapper.vm.observer.disconnect)).toBe(JSON.stringify(disconnect))
163+
expect(wrapper.exists()).toBeFalsy()
164+
})
165+
166+
it('should clear the timeout on disconnect', (done) => {
167+
const wrapper = createComponent({ ...item, width: 300, height: 300, placeholder: 'https://ik.imagekit.io/6xhf1gnexgdgk/igor2_HJhiHMa54.png' })
168+
expect(wrapper.exists()).toBe(true)
169+
setTimeout(() => {
170+
wrapper.destroy()
171+
expect(wrapper.vm.timeOut).toBe(null)
172+
done()
173+
}, 500)
174+
})
175+
176+
it('should set the src and srcset methods', (done) => {
177+
const localVue = createLocalVue()
178+
const wrapper = mount(VueImageKit, {
179+
propsData: { ...item, width: 300, height: 300, placeholder: 'https://ik.imagekit.io/6xhf1gnexgdgk/igor2_HJhiHMa54.png' },
180+
localVue,
181+
stubs: {
182+
transition: false
183+
}
184+
})
185+
wrapper.vm.observer.disconnect = jest.fn()
186+
wrapper.vm.observer.disconnect = jest.fn()
187+
expect(wrapper.exists()).toBe(true)
188+
wrapper.vm.triggerIntersection({ isIntersecting: true })
189+
expect(wrapper.vm.timeOut).toBeNull()
190+
expect(wrapper.vm.showCanvas).toBeFalsy()
191+
const img = wrapper.find('.vue-image-kit__img')
192+
expect(img.exists()).toBe(true)
193+
const placeholder = wrapper.find('.vue-image-kit__placeholder')
194+
expect(placeholder.exists()).toBe(true)
195+
setTimeout(() => {
196+
const placeholderAgain = wrapper.find('.vue-image-kit__placeholder')
197+
expect(placeholderAgain.exists()).toBe(false)
198+
expect(wrapper.vm.timeOut).toBeNull()
199+
done()
200+
}, 301)
201+
})
143202

144203
it('should match snapshot', () => {
145204
const wrapper = createComponent({

0 commit comments

Comments
 (0)