Skip to content
This repository was archived by the owner on Jan 22, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,018 changes: 523 additions & 495 deletions dist/atcb.js

Large diffs are not rendered by default.

40 changes: 20 additions & 20 deletions dist/atcb.umd.cjs

Large diffs are not rendered by default.

3,402 changes: 3,348 additions & 54 deletions package-lock.json

Large diffs are not rendered by default.

10 changes: 8 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
},
"description": "Convenient Vue.js wrapper for the add to calendar button snippet, which lets you reliably create beautiful buttons, where people can add events to their calendars.",
"type": "module",
"files": ["dist"],
"files": [
"dist"
],
"main": "./dist/atcb.umd.cjs",
"module": "./dist/atcb.js",
"types": "./dist/AddToCalendarButtonComponent.vue.d.ts",
Expand Down Expand Up @@ -54,14 +56,16 @@
"prettier": "npx prettier . --check",
"prettier:fix": "npm run prettier -- --write",
"format": "npm run eslint:fix && npm run prettier:fix",
"test": "echo \"Error: no test specified\" && exit 0",
"test": "vitest",
"serve": "vite preview",
"build": "vite build && vue-tsc --emitDeclarationOnly"
},
"dependencies": {
"add-to-calendar-button": "~1.18.5"
},
"devDependencies": {
"@testing-library/vue": "^6.6.1",
"@types/jest": "^29.2.1",
"@types/node": "^18.11.4",
"@typescript-eslint/eslint-plugin": "^5.41.0",
"@typescript-eslint/parser": "^5.41.0",
Expand All @@ -70,9 +74,11 @@
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-commonjs": "^1.0.2",
"eslint-plugin-security": "^1.5.0",
"jsdom": "^20.0.2",
"prettier": "2.7.1",
"typescript": "^4.8.4",
"vite": "^3.1.8",
"vitest": "^0.24.5",
"vue": "^3.2.41",
"vue-tsc": "^1.0.9"
},
Expand Down
7 changes: 7 additions & 0 deletions tests/mocks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const defaultProps = {
name: 'Test',
startDate: '2055-02-25',
options: ['Google', 'iCal'],
};

export const invalidOptionsPropValue = ['Googling'];
35 changes: 35 additions & 0 deletions tests/unit/basic.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { expect, test } from 'vitest';
import AddToCalendarButtonComponent from '@/components/AddToCalendarButtonComponent.vue';
import { render } from '@testing-library/vue';
import { defaultProps } from '@tests/mocks';

test('is imported and mounted', () => {
expect(AddToCalendarButtonComponent).toBeTruthy();

const component = render(AddToCalendarButtonComponent, {
props: defaultProps,
});

expect(component).toBeTruthy();
expect(component.container.querySelector('.atcb-initialized')).toBeTruthy();
});

test('is rerendered based on prop', async () => {
const initialLabel = 'Initial Label';
const changedLabel = 'Changed Label';

const component = render(AddToCalendarButtonComponent, {
props: {
...defaultProps,
label: initialLabel,
},
});

expect(component.getByText(initialLabel)).toBeTruthy();

await component.rerender({
label: changedLabel,
});

expect(component.getByText(changedLabel)).toBeTruthy();
});
45 changes: 45 additions & 0 deletions tests/unit/props_validation/required.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { expect, test, describe, vi } from 'vitest';
import AddToCalendarButtonComponent from '@/components/AddToCalendarButtonComponent.vue';
import { render } from '@testing-library/vue';
import { defaultProps } from '@tests/mocks';

describe('required props validation', () => {
test('is rendered with required `startDate` prop passed', () => {
const component = render(AddToCalendarButtonComponent, {
props: defaultProps,
});

expect(component).toBeTruthy();
expect(component.container.querySelector('.atcb-initialized')).toBeTruthy();
});

test('is rendered with required `dates` prop passed', () => {
const component = render(AddToCalendarButtonComponent, {
props: {
name: defaultProps.name,
dates: [{ name: 'Sub-Event', startDate: '2055-02-25' }],
options: defaultProps.options,
},
});

expect(component).toBeTruthy();
expect(component.container.querySelector('.atcb-initialized')).toBeTruthy();
});

test('is not rendered withouth required props passed', () => {
const spy = vi.spyOn(global.console, 'error');

const component = render(AddToCalendarButtonComponent, {
props: {
name: defaultProps.name,
options: defaultProps.options,
},
});

expect(spy).toHaveBeenCalledTimes(1);
expect(Array.isArray(spy.mock.lastCall) ? spy.mock.lastCall.join() : '').toContain(
'required setting missing'
);
expect(component.container.querySelector('.atcb-initialized')).toBeFalsy();
});
});
51 changes: 51 additions & 0 deletions tests/unit/props_validation/type.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { expect, test, describe, vi } from 'vitest';
import AddToCalendarButtonComponent from '@/components/AddToCalendarButtonComponent.vue';
import { render } from '@testing-library/vue';
import { defaultProps } from '@tests/mocks';

describe('props type validation', () => {
test('is rendered with proper-type properties', () => {
const component = render(AddToCalendarButtonComponent, {
props: {
...defaultProps,
sequence: 1,
},
});

expect(component).toBeTruthy();
expect(component.container.querySelector('.atcb-initialized')).toBeTruthy();
});

test('is not rendered with wrong types `options` prop', () => {
const spy = vi.spyOn(global.console, 'error');

const component = render(AddToCalendarButtonComponent, {
props: {
name: defaultProps.name,
startDate: defaultProps.startDate,
options: "['Google', 'iCal']",
},
});

expect(spy).toHaveBeenCalledTimes(1);
expect(Array.isArray(spy.mock.lastCall) ? spy.mock.lastCall.join() : '').toContain('invalid option [[]');
expect(component.container.querySelector('.atcb-initialized')).toBeFalsy();
});

test('is not rendered with wrong types `sequence` prop', () => {
const spy = vi.spyOn(global.console, 'log');

const component = render(AddToCalendarButtonComponent, {
props: {
...defaultProps,
sequence: 'text',
},
});

expect(spy).toHaveBeenCalled();
expect(Array.isArray(spy.mock.calls[0]) ? spy.mock.calls[0].join() : '').toContain(
'sequence needs to be a number. Used the default 0 instead'
);
expect(component.container.querySelector('.atcb-initialized')).toBeTruthy();
});
});
87 changes: 87 additions & 0 deletions tests/unit/props_validation/value.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { expect, test, describe, vi } from 'vitest';
import AddToCalendarButtonComponent from '@/components/AddToCalendarButtonComponent.vue';
import { render } from '@testing-library/vue';
import { defaultProps, invalidOptionsPropValue } from '@tests/mocks';

describe('props value validation', () => {
test('is rendered with proper-value properties', () => {
const component = render(AddToCalendarButtonComponent, {
props: defaultProps,
});

expect(component).toBeTruthy();
expect(component.container.querySelector('.atcb-initialized')).toBeTruthy();
});

test('is not rendered with invalid `option` prop value', () => {
const spy = vi.spyOn(global.console, 'error');

const component = render(AddToCalendarButtonComponent, {
props: {
name: defaultProps.name,
startDate: defaultProps.startDate,
options: invalidOptionsPropValue,
},
});

expect(spy).toHaveBeenCalledTimes(1);
expect(Array.isArray(spy.mock.lastCall) ? spy.mock.lastCall.join() : '').toContain(
`invalid option [${invalidOptionsPropValue.join().toLowerCase()}]`
);
expect(component.container.querySelector('.atcb-initialized')).toBeFalsy();
});

test('is not rendered with endDate before startDate', () => {
const spy = vi.spyOn(global.console, 'error');

const component = render(AddToCalendarButtonComponent, {
props: {
...defaultProps,
startTime: '14:00',
endDate: '2055-02-25',
endTime: '13:00',
},
});

expect(spy).toHaveBeenCalledTimes(1);
expect(Array.isArray(spy.mock.lastCall) ? spy.mock.lastCall.join() : '').toContain(
'end date before start date'
);
expect(component.container.querySelector('.atcb-initialized')).toBeFalsy();
});

test('is rendered with proper `timeZone` prop value', () => {
const component = render(AddToCalendarButtonComponent, {
props: {
...defaultProps,
startTime: '14:00',
endDate: '2055-02-25',
endTime: '15:00',
timeZone: 'Europe/Paris',
},
});

expect(component).toBeTruthy();
expect(component.container.querySelector('.atcb-initialized')).toBeTruthy();
});

test('is not rendered with invalid timezone', () => {
const spy = vi.spyOn(global.console, 'error');

const component = render(AddToCalendarButtonComponent, {
props: {
...defaultProps,
startTime: '14:00',
endDate: '2055-02-25',
endTime: '15:00',
timeZone: 'Europe/FantasyCity',
},
});

expect(spy).toHaveBeenCalledTimes(1);
expect(Array.isArray(spy.mock.lastCall) ? spy.mock.lastCall.join() : '').toContain(
'invalid time zone given'
);
expect(component.container.querySelector('.atcb-initialized')).toBeFalsy();
});
});
11 changes: 8 additions & 3 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,13 @@
"lib": ["ESNext", "DOM"],
"skipLibCheck": true,
"outDir": "dist",
"declaration": true
"declaration": true,
"baseUrl": "./",
"paths": {
"@/*": ["src/*"],
"@tests/*": ["tests/*"]
}
},
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
"references": [{ "path": "./tsconfig.node.json" }],
}
"references": [{ "path": "./tsconfig.node.json" }]
}
32 changes: 22 additions & 10 deletions vite.config.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,34 @@
import { resolve } from 'path'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path';
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';

export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
'@': resolve(__dirname, 'src'),
'@tests': resolve(__dirname, 'tests'),
},
},
build: {
lib: {
entry: resolve(__dirname, 'src/components/AddToCalendarButtonComponent.vue'),
name: 'add-to-calendar-button',
fileName: 'atcb'
fileName: 'atcb',
},
rollupOptions: {
external: ['vue'],
output: {
globals: {
vue: 'Vue'
}
}
}
}
})
vue: 'Vue',
},
},
},
},
test: {
globals: true,
environment: 'jsdom',
silent: true,
watch: false,
},
});