Skip to content

Commit

Permalink
test: setup unit tests suite using Jest
Browse files Browse the repository at this point in the history
  • Loading branch information
LeBenLeBen committed Jan 19, 2021
1 parent f5729b1 commit 728a4ec
Show file tree
Hide file tree
Showing 8 changed files with 2,364 additions and 85 deletions.
12 changes: 0 additions & 12 deletions .babelrc

This file was deleted.

13 changes: 13 additions & 0 deletions babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module.exports = {
presets: [
[
'@babel/preset-env',
{
// Jest tests are run in Node and it requires commonjs modules
modules: process.env.NODE_ENV === 'test' ? 'commonjs' : false,
loose: true
}
]
],
plugins: ['@vue/babel-plugin-jsx']
}
5 changes: 5 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = {
transform: {
'\\.[jt]sx?$': 'babel-jest'
}
}
8 changes: 7 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
"sideEffects": false,
"scripts": {
"prepublishOnly": "npm run build",
"test": "echo fine",
"test": "jest",
"test:dev": "jest --watch",
"build": "bili",
"storybook": "poi -so --config stories/poi.config.js",
"build:storybook": "poi --prod --config stories/poi.config.js"
Expand All @@ -28,10 +29,15 @@
},
"license": "MIT",
"devDependencies": {
"@babel/core": "^7.12.10",
"@babel/preset-env": "^7.12.11",
"@types/poi": "^12.5.0",
"@vue/babel-plugin-jsx": "^1.0.2",
"@vue/compiler-sfc": "^3.0.5",
"@vue/test-utils": "^2.0.0-beta.14",
"babel-jest": "^26.6.3",
"bili": "^5.0.5",
"jest": "^26.6.3",
"poi": "12.10.3",
"vue": "^3.0.5",
"vue-loader": "^16.1.2",
Expand Down
198 changes: 198 additions & 0 deletions src/ContentLoader.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
import { mount } from '@vue/test-utils'
import ContentLoader from './ContentLoader'

describe('ContentLoader', () => {
it('has default values for props', () => {
const wrapper = mount(ContentLoader)

expect(wrapper.vm.width).toBe(400)
expect(wrapper.vm.height).toBe(130)
expect(wrapper.vm.speed).toBe(2)
expect(wrapper.vm.preserveAspectRatio).toBe('xMidYMid meet')
expect(wrapper.vm.baseUrl).toBe('')
expect(wrapper.vm.primaryColor).toBe('#f9f9f9')
expect(wrapper.vm.secondaryColor).toBe('#ecebeb')
expect(wrapper.vm.primaryOpacity).toBe(1)
expect(wrapper.vm.secondaryOpacity).toBe(1)
expect(wrapper.vm.animate).toBe(true)
})

it('has viewbox, version and aspect ratio attributes on svg element', () => {
const wrapper = mount(ContentLoader, {
props: {
width: 300,
height: 200,
preserveAspectRatio: 'xMaxYMid slice'
}
})

expect(wrapper.find('svg').attributes()).toEqual({
preserveAspectRatio: 'xMaxYMid slice',
version: '1.1',
viewBox: '0 0 300 200'
})
})

it('has viewbox, version and aspect ratio attributes on svg element', () => {
const wrapper = mount(ContentLoader, {
props: {
width: 300,
height: 200,
preserveAspectRatio: 'xMaxYMid slice'
}
})

expect(wrapper.find('svg').attributes()).toEqual({
preserveAspectRatio: 'xMaxYMid slice',
version: '1.1',
viewBox: '0 0 300 200'
})
})

it('draws a rect filled by the gradient and clipped by the shapes', () => {
const wrapper = mount(ContentLoader)

expect(wrapper.find('rect').attributes()).toEqual({
style: `fill: url(#${wrapper.vm.idGradient});`,
'clip-path': `url(#${wrapper.vm.idClip})`,
x: '0',
y: '0',
width: '400',
height: '130'
})
})

it('draws a clipPath with a unique ID', () => {
const wrapper = mount(ContentLoader)

expect(wrapper.find('defs clipPath').attributes()).toEqual({
id: wrapper.vm.idClip
})
})

it('draws a linear gradient with a unique ID', () => {
const wrapper = mount(ContentLoader)

expect(wrapper.find('defs linearGradient').attributes()).toEqual({
id: wrapper.vm.idGradient
})
})

it('draws a linear gradient with 3 stops', () => {
const wrapper = mount(ContentLoader)
const stops = wrapper.findAll('defs linearGradient stop')

expect(stops.length).toBe(3)
expect(stops[0].attributes()).toEqual({
offset: '0%',
'stop-color': '#f9f9f9',
'stop-opacity': '1'
})
expect(stops[1].attributes()).toEqual({
offset: '50%',
'stop-color': '#ecebeb',
'stop-opacity': '1'
})
expect(stops[2].attributes()).toEqual({
offset: '100%',
'stop-color': '#f9f9f9',
'stop-opacity': '1'
})
})

it('animates the gradient by default using given speed', () => {
const wrapper = mount(ContentLoader)
const animations = wrapper.findAll('defs linearGradient animate')

expect(animations.length).toBe(3)
expect(animations[0].attributes()).toEqual({
attributeName: 'offset',
values: '-2; 1',
dur: '2s',
repeatCount: 'indefinite'
})
expect(animations[1].attributes()).toEqual({
attributeName: 'offset',
values: '-1.5; 1.5',
dur: '2s',
repeatCount: 'indefinite'
})
expect(animations[2].attributes()).toEqual({
attributeName: 'offset',
values: '-1; 2',
dur: '2s',
repeatCount: 'indefinite'
})
})

it('does not animate if animate prop is false', () => {
const wrapper = mount(ContentLoader, {
props: {
animate: false
}
})

expect(wrapper.findAll('defs linearGradient animate').length).toBe(0)
})

it('has a default element to clip with', () => {
const wrapper = mount(ContentLoader)

expect(wrapper.find('defs clipPath rect').attributes()).toEqual({
x: '0',
y: '0',
rx: '5',
ry: '5',
width: '400',
height: '130'
})
})

it('outputs the default slot within the clipPath', () => {
const wrapper = mount(ContentLoader, {
slots: {
default: '<circle cx="30" cy="30" r="30" />'
}
})

expect(wrapper.find('defs clipPath circle').html()).toEqual(
'<circle cx="30" cy="30" r="30"></circle>'
)
})

it('use the baseUrl to link the gradient & clip path', () => {
const wrapper = mount(ContentLoader, {
props: {
baseUrl: '/path'
}
})

expect(wrapper.find('rect').attributes()).toMatchObject({
style: `fill: url(/path#${wrapper.vm.idGradient});`,
'clip-path': `url(/path#${wrapper.vm.idClip})`
})
})

it('use the uniqueKey to generate static IDs', () => {
const wrapper = mount(ContentLoader, {
props: {
uniqueKey: 'unique'
}
})

expect(wrapper.vm.idClip).toEqual('unique-idClip')
expect(wrapper.vm.idGradient).toEqual('unique-idGradient')
})

it('apply extra attributes on the root element', () => {
const wrapper = mount(ContentLoader, {
props: {
class: 'loader',
id: 'loader'
}
})

expect(wrapper.find('svg').classes()).toEqual(['loader'])
expect(wrapper.find('svg').attributes()).toMatchObject({ id: 'loader' })
})
})
59 changes: 59 additions & 0 deletions src/__snapshots__/index.spec.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`BulletListLoader renders its shapes 1`] = `
Array [
"<circle cx=\\"10\\" cy=\\"20\\" r=\\"8\\"></circle>",
"<rect x=\\"25\\" y=\\"15\\" rx=\\"5\\" ry=\\"5\\" width=\\"220\\" height=\\"10\\"></rect>",
"<circle cx=\\"10\\" cy=\\"50\\" r=\\"8\\"></circle>",
"<rect x=\\"25\\" y=\\"45\\" rx=\\"5\\" ry=\\"5\\" width=\\"220\\" height=\\"10\\"></rect>",
"<circle cx=\\"10\\" cy=\\"80\\" r=\\"8\\"></circle>",
"<rect x=\\"25\\" y=\\"75\\" rx=\\"5\\" ry=\\"5\\" width=\\"220\\" height=\\"10\\"></rect>",
"<circle cx=\\"10\\" cy=\\"110\\" r=\\"8\\"></circle>",
"<rect x=\\"25\\" y=\\"105\\" rx=\\"5\\" ry=\\"5\\" width=\\"220\\" height=\\"10\\"></rect>",
]
`;
exports[`CodeLoader renders its shapes 1`] = `
Array [
"<rect x=\\"0\\" y=\\"0\\" rx=\\"3\\" ry=\\"3\\" width=\\"70\\" height=\\"10\\"></rect>",
"<rect x=\\"80\\" y=\\"0\\" rx=\\"3\\" ry=\\"3\\" width=\\"100\\" height=\\"10\\"></rect>",
"<rect x=\\"190\\" y=\\"0\\" rx=\\"3\\" ry=\\"3\\" width=\\"10\\" height=\\"10\\"></rect>",
"<rect x=\\"15\\" y=\\"20\\" rx=\\"3\\" ry=\\"3\\" width=\\"130\\" height=\\"10\\"></rect>",
"<rect x=\\"155\\" y=\\"20\\" rx=\\"3\\" ry=\\"3\\" width=\\"130\\" height=\\"10\\"></rect>",
"<rect x=\\"15\\" y=\\"40\\" rx=\\"3\\" ry=\\"3\\" width=\\"90\\" height=\\"10\\"></rect>",
"<rect x=\\"115\\" y=\\"40\\" rx=\\"3\\" ry=\\"3\\" width=\\"60\\" height=\\"10\\"></rect>",
"<rect x=\\"185\\" y=\\"40\\" rx=\\"3\\" ry=\\"3\\" width=\\"60\\" height=\\"10\\"></rect>",
"<rect x=\\"0\\" y=\\"60\\" rx=\\"3\\" ry=\\"3\\" width=\\"30\\" height=\\"10\\"></rect>",
]
`;
exports[`FacebookLoader renders its shapes 1`] = `
Array [
"<rect x=\\"70\\" y=\\"15\\" rx=\\"4\\" ry=\\"4\\" width=\\"117\\" height=\\"6.4\\"></rect>",
"<rect x=\\"70\\" y=\\"35\\" rx=\\"3\\" ry=\\"3\\" width=\\"85\\" height=\\"6.4\\"></rect>",
"<rect x=\\"0\\" y=\\"80\\" rx=\\"3\\" ry=\\"3\\" width=\\"350\\" height=\\"6.4\\"></rect>",
"<rect x=\\"0\\" y=\\"100\\" rx=\\"3\\" ry=\\"3\\" width=\\"380\\" height=\\"6.4\\"></rect>",
"<rect x=\\"0\\" y=\\"120\\" rx=\\"3\\" ry=\\"3\\" width=\\"201\\" height=\\"6.4\\"></rect>",
"<circle cx=\\"30\\" cy=\\"30\\" r=\\"30\\"></circle>",
]
`;
exports[`InstagramLoader renders its shapes 1`] = `
Array [
"<circle cx=\\"30\\" cy=\\"30\\" r=\\"30\\"></circle>",
"<rect x=\\"75\\" y=\\"13\\" rx=\\"4\\" ry=\\"4\\" width=\\"100\\" height=\\"13\\"></rect>",
"<rect x=\\"75\\" y=\\"37\\" rx=\\"4\\" ry=\\"4\\" width=\\"50\\" height=\\"8\\"></rect>",
"<rect x=\\"0\\" y=\\"70\\" rx=\\"5\\" ry=\\"5\\" width=\\"400\\" height=\\"400\\"></rect>",
]
`;
exports[`ListLoader renders its shapes 1`] = `
Array [
"<rect x=\\"0\\" y=\\"0\\" rx=\\"3\\" ry=\\"3\\" width=\\"250\\" height=\\"10\\"></rect>",
"<rect x=\\"20\\" y=\\"20\\" rx=\\"3\\" ry=\\"3\\" width=\\"220\\" height=\\"10\\"></rect>",
"<rect x=\\"20\\" y=\\"40\\" rx=\\"3\\" ry=\\"3\\" width=\\"170\\" height=\\"10\\"></rect>",
"<rect x=\\"0\\" y=\\"60\\" rx=\\"3\\" ry=\\"3\\" width=\\"250\\" height=\\"10\\"></rect>",
"<rect x=\\"20\\" y=\\"80\\" rx=\\"3\\" ry=\\"3\\" width=\\"200\\" height=\\"10\\"></rect>",
"<rect x=\\"20\\" y=\\"100\\" rx=\\"3\\" ry=\\"3\\" width=\\"80\\" height=\\"10\\"></rect>",
]
`;
35 changes: 35 additions & 0 deletions src/index.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { mount } from '@vue/test-utils'

import BulletListLoader from './BulletListLoader'
import CodeLoader from './CodeLoader'
import FacebookLoader from './FacebookLoader'
import ListLoader from './ListLoader'
import InstagramLoader from './InstagramLoader'

describe.each([
['BulletListLoader', BulletListLoader],
['CodeLoader', CodeLoader],
['FacebookLoader', FacebookLoader],
['ListLoader', ListLoader],
['InstagramLoader', InstagramLoader]
])('%s', (name, component) => {
it('renders its shapes', () => {
const wrapper = mount(component)

expect(wrapper.findAll('clipPath > *').map(c => c.html())).toMatchSnapshot()
})

it('forwards attributes to ContentLoader', () => {
const wrapper = mount(component, {
props: {
id: 'loader',
class: 'loader'
}
})

expect(wrapper.attributes()).toMatchObject({
id: 'loader',
class: 'loader'
})
})
})
Loading

0 comments on commit 728a4ec

Please sign in to comment.