Merge vitest

This commit is contained in:
Sidharth Vinod
2022-09-20 23:51:21 +05:30
parent e0aae3e31f
commit 3b30232e88
27 changed files with 657 additions and 1660 deletions

View File

@@ -1,3 +0,0 @@
module.exports = function (txt) {
return txt;
};

View File

@@ -1,18 +1,15 @@
/**
* Mocks for `./mermaidAPI`.
*
* We can't easily use `jest.spyOn(mermaidAPI, "function")` since the object is frozen with `Object.freeze()`.
* We can't easily use `vi.spyOn(mermaidAPI, "function")` since the object is frozen with `Object.freeze()`.
*/
import * as configApi from '../config';
import { vi } from 'vitest';
import { addDiagrams } from '../diagram-api/diagram-orchestration';
import Diagram from '../Diagram';
// Normally, we could just do the following to get the original `parse()`
// implementation, however, requireActual isn't currently supported in Jest
// for ESM, see https://github.com/facebook/jest/issues/9430
// and https://github.com/facebook/jest/pull/10976
// const {parse} = jest.requireActual("./mermaidAPI");
// implementation, however, requireActual returns a promise and it's not documented how to use withing mock file.
let hasLoadedDiagrams = false;
/**
@@ -31,10 +28,10 @@ function parse(text: string, parseError?: Function): boolean {
// original version cannot be modified since it was frozen with `Object.freeze()`
export const mermaidAPI = {
render: jest.fn(),
render: vi.fn(),
parse,
parseDirective: jest.fn(),
initialize: jest.fn(),
parseDirective: vi.fn(),
initialize: vi.fn(),
getConfig: configApi.getConfig,
setConfig: configApi.setConfig,
getSiteConfig: configApi.getSiteConfig,

View File

@@ -1,7 +1,7 @@
import { parser } from './parser/classDiagram';
import classDb from './classDb';
const spyOn = jest.spyOn;
import { vi } from 'vitest';
const spyOn = vi.spyOn;
describe('class diagram, ', function () {
describe('when parsing an info graph it', function () {
@@ -14,7 +14,7 @@ describe('class diagram, ', function () {
parser.parse(str);
});
xit('should handle a leading newline axa', function () {
it.skip('should handle a leading newline axa', function () {
const str = '\nclassDiagram\n' + 'class Car';
try {

View File

@@ -4,9 +4,6 @@ import flowRenderer from './flowRenderer';
import Diagram from '../../Diagram';
import { addDiagrams } from '../../diagram-api/diagram-orchestration';
addDiagrams();
afterEach(() => {
jest.restoreAllMocks();
});
describe('when using mermaid and ', function () {
describe('when calling addEdges ', function () {

View File

@@ -1,8 +1,8 @@
import flowDb from '../flowDb';
import flow from './flow';
import { setConfig } from '../../../config';
const spyOn = jest.spyOn;
import { vi } from 'vitest';
const spyOn = vi.spyOn;
setConfig({
securityLevel: 'strict',

View File

@@ -284,7 +284,7 @@ describe('[Text] when parsing', () => {
expect(edges[0].text).toBe('text including graph space and v');
});
// xit('should handle text on open links',function(){
// it.skip('should handle text on open links',function(){
// const res = flow.parser.parse('graph TD;A-- text including graph space --B');
//
// const vert = flow.parser.yy.getVertices();
@@ -324,7 +324,7 @@ describe('[Text] when parsing', () => {
expect(vert['C'].type).toBe('round');
expect(vert['C'].text).toBe('Chimpansen hoppar åäö <br> - ÅÄÖ');
});
// xit('should handle åäö, minus and space and br',function(){
// it.skip('should handle åäö, minus and space and br',function(){
// const res = flow.parser.parse('graph TD; A[Object&#40;foo,bar&#41;]-->B(Thing);');
//
// const vert = flow.parser.yy.getVertices();

View File

@@ -62,7 +62,7 @@ describe('when parsing subgraphs', function () {
expect(subgraph.id).toBe('some-id');
});
xit('should handle subgraph without id and space in title', function () {
it.skip('should handle subgraph without id and space in title', function () {
const res = flow.parser.parse('graph TB\nsubgraph Some Title\n\ta1-->a2\nend');
const subgraphs = flow.parser.yy.getSubGraphs();
expect(subgraphs.length).toBe(1);

View File

@@ -1,5 +1,8 @@
// @ts-nocheck TODO: Fix TS
import moment from 'moment-mini';
import ganttDb from './ganttDb';
import { it, describe } from 'vitest';
import { convert } from '../../tests/util';
describe('when using the ganttDb', function () {
beforeEach(function () {
@@ -7,14 +10,23 @@ describe('when using the ganttDb', function () {
});
describe('when using duration', function () {
it.each`
it.each([{ str: '1d', expected: moment.duration(1, 'd') }])(
'should %s resulting in $o duration',
({ str, expected }) => {
expect(ganttDb.parseDuration(str)).toEqual(expected);
}
);
it.each(
convert`
str | expected
${'1d'} | ${moment.duration(1, 'd')}
${'2w'} | ${moment.duration(2, 'w')}
${'1ms'} | ${moment.duration(1, 'ms')}
${'0.1s'} | ${moment.duration(100, 'ms')}
${'1f'} | ${moment.duration.invalid()}
`('should $str resulting in $expected duration', ({ str, expected }) => {
`
)('should $str resulting in $expected duration', ({ str, expected }) => {
expect(ganttDb.parseDuration(str)).toEqual(expected);
});
});
@@ -31,7 +43,7 @@ describe('when using the ganttDb', function () {
ganttDb.clear();
});
it.each`
it.each(convert`
fn | expected
${'getTasks'} | ${[]}
${'getAccTitle'} | ${''}
@@ -42,12 +54,13 @@ describe('when using the ganttDb', function () {
${'getExcludes'} | ${[]}
${'getSections'} | ${[]}
${'endDatesAreInclusive'} | ${false}
`('should clear $fn', ({ fn, expected }) => {
`)('should clear $fn', ({ fn, expected }) => {
expect(ganttDb[fn]()).toEqual(expected);
});
});
it.each`
// prettier-ignore
it.each(convert`
testName | section | taskName | taskData | expStartDate | expEndDate | expId | expTask
${'should handle fixed dates'} | ${'testa1'} | ${'test1'} | ${'id1,2013-01-01,2013-01-12'} | ${new Date(2013, 0, 1)} | ${new Date(2013, 0, 12)} | ${'id1'} | ${'test1'}
${'should handle duration (days) instead of fixed date to determine end date'} | ${'testa1'} | ${'test1'} | ${'id1,2013-01-01,2d'} | ${new Date(2013, 0, 1)} | ${new Date(2013, 0, 3)} | ${'id1'} | ${'test1'}
@@ -57,7 +70,7 @@ describe('when using the ganttDb', function () {
${'should handle duration (weeks) instead of fixed date to determine end date'} | ${'testa1'} | ${'test1'} | ${'id1,2013-01-01,2w'} | ${new Date(2013, 0, 1)} | ${new Date(2013, 0, 15)} | ${'id1'} | ${'test1'}
${'should handle fixed dates without id'} | ${'testa1'} | ${'test1'} | ${'2013-01-01,2013-01-12'} | ${new Date(2013, 0, 1)} | ${new Date(2013, 0, 12)} | ${'task1'} | ${'test1'}
${'should handle duration instead of a fixed date to determine end date without id'} | ${'testa1'} | ${'test1'} | ${'2013-01-01,4d'} | ${new Date(2013, 0, 1)} | ${new Date(2013, 0, 5)} | ${'task1'} | ${'test1'}
`('$testName', ({ section, taskName, taskData, expStartDate, expEndDate, expId, expTask }) => {
`)('$testName', ({ section, taskName, taskData, expStartDate, expEndDate, expId, expTask }) => {
ganttDb.setDateFormat('YYYY-MM-DD');
ganttDb.addSection(section);
ganttDb.addTask(taskName, taskData);
@@ -68,14 +81,15 @@ describe('when using the ganttDb', function () {
expect(tasks[0].task).toEqual(expTask);
});
it.each`
// prettier-ignore
it.each(convert`
section | taskName1 | taskName2 | taskData1 | taskData2 | expStartDate2 | expEndDate2 | expId2 | expTask2
${'testa1'} | ${'test1'} | ${'test2'} | ${'id1,2013-01-01,2w'} | ${'id2,after id1,1d'} | ${new Date(2013, 0, 15)} | ${undefined} | ${'id2'} | ${'test2'}
${'testa1'} | ${'test1'} | ${'test2'} | ${'id1,2013-01-01,2w'} | ${'id2,after id3,1d'} | ${new Date(new Date().setHours(0, 0, 0, 0))} | ${undefined} | ${'id2'} | ${'test2'}
${'testa1'} | ${'test1'} | ${'test2'} | ${'id1,2013-01-01,2w'} | ${'after id1,1d'} | ${new Date(2013, 0, 15)} | ${undefined} | ${'task1'} | ${'test2'}
${'testa1'} | ${'test1'} | ${'test2'} | ${'id1,2013-01-01,2w'} | ${'2013-01-26'} | ${new Date(2013, 0, 15)} | ${new Date(2013, 0, 26)} | ${'task1'} | ${'test2'}
${'testa1'} | ${'test1'} | ${'test2'} | ${'id1,2013-01-01,2w'} | ${'2d'} | ${new Date(2013, 0, 15)} | ${new Date(2013, 0, 17)} | ${'task1'} | ${'test2'}
`(
`)(
'$testName',
({
section,
@@ -381,11 +395,11 @@ describe('when using the ganttDb', function () {
});
});
it.each`
it.each(convert`
type | expected
${'hide'} | ${'off'}
${'style'} | ${'stoke:stroke-width:5px,stroke:#00f,opacity:0.5'}
`('should ${type} today marker', ({ expected }) => {
`)('should ${type} today marker', ({ expected }) => {
ganttDb.setTodayMarker(expected);
expect(ganttDb.getTodayMarker()).toEqual(expected);
});

View File

@@ -1,7 +1,8 @@
import { parser } from './gantt';
import ganttDb from '../ganttDb';
const spyOn = jest.spyOn;
import { convert } from '../../../tests/util';
import { vi } from 'vitest';
const spyOn = vi.spyOn;
const parserFnConstructor = (str) => {
return () => {
parser.parse(str);
@@ -92,14 +93,14 @@ describe('when parsing a gantt diagram it', function () {
expect(tasks[0].id).toEqual('des1');
expect(tasks[0].task).toEqual('Design jison grammar');
});
it.each`
it.each(convert`
tags | milestone | done | crit | active
${'milestone'} | ${true} | ${false} | ${false} | ${false}
${'done'} | ${false} | ${true} | ${false} | ${false}
${'crit'} | ${false} | ${false} | ${true} | ${false}
${'active'} | ${false} | ${false} | ${false} | ${true}
${'crit,milestone,done'} | ${true} | ${true} | ${true} | ${false}
`('should handle a task with tags $tags', ({ tags, milestone, done, crit, active }) => {
`)('should handle a task with tags $tags', ({ tags, milestone, done, crit, active }) => {
const str =
'gantt\n' +
'dateFormat YYYY-MM-DD\n' +

View File

@@ -25,15 +25,15 @@ describe('more than one sequence diagram', () => {
Alice->Bob:Hello Bob, how are you?
Bob-->Alice: I am good thanks!`);
expect(diagram1.db.getMessages()).toMatchInlineSnapshot(`
Array [
Object {
[
{
"from": "Alice",
"message": "Hello Bob, how are you?",
"to": "Bob",
"type": 5,
"wrap": false,
},
Object {
{
"from": "Bob",
"message": "I am good thanks!",
"to": "Alice",
@@ -48,15 +48,15 @@ describe('more than one sequence diagram', () => {
Bob-->Alice: I am good thanks!`);
expect(diagram2.db.getMessages()).toMatchInlineSnapshot(`
Array [
Object {
[
{
"from": "Alice",
"message": "Hello Bob, how are you?",
"to": "Bob",
"type": 5,
"wrap": false,
},
Object {
{
"from": "Bob",
"message": "I am good thanks!",
"to": "Alice",
@@ -73,15 +73,15 @@ describe('more than one sequence diagram', () => {
John-->Alice: I am good thanks!`);
expect(diagram3.db.getMessages()).toMatchInlineSnapshot(`
Array [
Object {
[
{
"from": "Alice",
"message": "Hello John, how are you?",
"to": "John",
"type": 5,
"wrap": false,
},
Object {
{
"from": "John",
"message": "I am good thanks!",
"to": "Alice",

View File

@@ -389,7 +389,7 @@ describe('state diagram, ', function () {
});
});
describe('when parsing an ignored info graph it', function () {
xit('should handle if statements', function () {
it.skip('should handle if statements', function () {
const str = `stateDiagram\n
[*] --> "Order Submitted"
if "Payment Accepted" then

View File

@@ -1,4 +1,5 @@
import journeyDb from './journeyDb';
import { convert } from '../../tests/util';
describe('when using the journeyDb', function () {
beforeEach(function () {
@@ -13,13 +14,13 @@ describe('when using the journeyDb', function () {
journeyDb.clear();
});
it.each`
it.each(convert`
fn | expected
${'getTasks'} | ${[]}
${'getAccTitle'} | ${''}
${'getSections'} | ${[]}
${'getActors'} | ${[]}
`('should clear $fn', ({ fn, expected }) => {
`)('should clear $fn', ({ fn, expected }) => {
expect(journeyDb[fn]()).toEqual(expected);
});
});
@@ -31,18 +32,18 @@ describe('when using the journeyDb', function () {
journeyDb.addTask('test2', '1: id2');
journeyDb.clear();
});
it.each`
it.each(convert`
fn | expected
${'getTasks'} | ${[]}
${'getAccTitle'} | ${''}
${'getAccDescription'} | ${''}
${'getSections'} | ${[]}
`('should clear $fn', ({ fn, expected }) => {
`)('should clear $fn', ({ fn, expected }) => {
expect(journeyDb[fn]()).toEqual(expected);
});
});
describe('tasks and actors should be added', function () {
it('tasks and actors should be added', function () {
journeyDb.setAccTitle('Shopping');
journeyDb.setAccDescription('A user journey for family shopping');
journeyDb.addSection('Journey to the shops');

View File

@@ -1,19 +1,12 @@
// mocks the mermaidAPI.render function (see `./__mocks__/mermaidAPI`)
jest.mock('./mermaidAPI');
// jest.mock only works well with CJS, see https://github.com/facebook/jest/issues/9430
// eslint-disable-next-line @typescript-eslint/no-var-requires
const { default: mermaid } = require('./mermaid');
// eslint-disable-next-line @typescript-eslint/no-var-requires
const { mermaidAPI } = require('./mermaidAPI');
// eslint-disable-next-line @typescript-eslint/no-var-requires
const { default: flowDb } = require('./diagrams/flowchart/flowDb');
import mermaid from './mermaid';
import { mermaidAPI } from './mermaidAPI';
import { vi, describe, it, beforeEach, afterEach, expect } from 'vitest';
const spyOn = vi.spyOn;
import flowParser from './diagrams/flowchart/parser/flow';
const spyOn = jest.spyOn;
vi.mock('./mermaidAPI');
afterEach(() => {
jest.restoreAllMocks();
vi.restoreAllMocks();
});
describe('when using mermaid and ', function () {
@@ -63,11 +56,6 @@ describe('when using mermaid and ', function () {
});
describe('checking validity of input ', function () {
beforeEach(function () {
flowParser.parser.yy = flowDb;
flowDb.clear();
flowDb.setGen('gen-2');
});
it('should throw for an invalid definition', function () {
expect(() => mermaid.parse('this is not a mermaid diagram definition')).toThrow();
});

3
src/tests/setup.ts Normal file
View File

@@ -0,0 +1,3 @@
import { vi } from 'vitest';
vi.mock('d3');
vi.mock('dagre-d3');

44
src/tests/util.ts Normal file
View File

@@ -0,0 +1,44 @@
/*
Used to convert jest's Tagged Template literals to object arrays as required by vitest.
Example:
Jest code
```ts
it.each`
str | expected
${'1d'} | ${moment.duration(1, 'd')}
${'2w'} | ${moment.duration(2, 'w')}
`('should parse $str to $expected duration', ({ str, expected }) => {
expect(yourFunction(str)).toEqual(expected);
});
```
Vitest code
```ts
it.each(convert`
str | expected
${'1d'} | ${moment.duration(1, 'd')}
${'2w'} | ${moment.duration(2, 'w')}
`)('should parse $str to $expected duration', ({ str, expected }) => {
expect(yourFunction(str)).toEqual(expected);
});
```
*/
export const convert = (template: TemplateStringsArray, ...params: any[]) => {
const header = template[0]
.trim()
.split('|')
.map((s) => s.trim());
if (header.length === 0 || params.length % header.length !== 0) {
throw new Error('Table column count mismatch');
}
const chunkSize = header.length;
const out = [];
for (let i = 0; i < params.length; i += chunkSize) {
const chunk = params.slice(i, i + chunkSize);
out.push(Object.fromEntries(chunk.map((v, i) => [header[i], v])));
}
return out;
};

View File

@@ -1,3 +1,4 @@
import { vi, describe, it, expect, beforeEach } from 'vitest';
import utils from './utils';
import assignWithDepth from './assignWithDepth';
import { detectType } from './diagram-api/detectType';
@@ -303,14 +304,22 @@ describe('when formatting urls', function () {
});
describe('when initializing the id generator', function () {
it('should return a random number generator based on Date', function (done) {
beforeEach(() => {
// tell vitest we use mocked time
vi.useFakeTimers();
});
afterEach(() => {
// restoring date after each test run
vi.useRealTimers();
});
it('should return a random number generator based on Date', function () {
const idGenerator = new utils.initIdGenerator(false);
expect(typeof idGenerator.next).toEqual('function');
const lastId = idGenerator.next();
setTimeout(() => {
expect(idGenerator.next() > lastId).toBe(true);
done();
}, 5);
vi.advanceTimersByTime(1000);
expect(idGenerator.next() > lastId).toBe(true);
});
it('should return a non random number generator', function () {