Skip to content

Commit

Permalink
start switching to vitest for esm support
Browse files Browse the repository at this point in the history
  • Loading branch information
domoritz committed Feb 12, 2025
1 parent 7febfa9 commit a9f0fb6
Show file tree
Hide file tree
Showing 13 changed files with 202 additions and 111 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@ site/examples
site/static/bundle.*
test/log
test/log/difflist.json
test-runtime/__screenshots__
yarn-debug.log*
yarn-error.log*
File renamed without changes.
47 changes: 18 additions & 29 deletions test-runtime/animation.test.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import {Datum} from 'vega';
import {TopLevelSpec} from '../src/index.js';
import {embedFn, getSignal, getState, setSignal, sleep, testRenderFn} from './util.js';
import {page} from '@vitest/browser/context';
import {embed, getSignal, getState, setSignal, sleep} from './util.js';
import {describe, expect, it} from 'vitest';

import gapminderData from './gapminder.json' with {type: 'json'};

const gapminderSpec: TopLevelSpec = {
$schema: 'https://vega.github.io/schema/vega-lite/v5.json',
data: {
url: 'gapminder.json',
values: gapminderData,
},
mark: 'point',
params: [
Expand Down Expand Up @@ -45,67 +47,54 @@ const gapminderSpec: TopLevelSpec = {
};

describe('time encoding animations', () => {
let embed: (specification: TopLevelSpec) => Promise<void>;
let testRender: (filename: string) => Promise<void>;

beforeAll(async () => {
embed = embedFn();
testRender = testRenderFn(page, 'animation');
await page.goto('http://0.0.0.0:9000/test-runtime/');
});

afterAll(async () => {
await page.close();
});

it('renders a frame for each anim_value', async () => {
await embed(gapminderSpec);
const view = await embed(gapminderSpec);

await page.evaluate(setSignal('is_playing', false));
expect(await getSignal(view, 'is_playing')).toBe(false);

const domain = [1955, 1960, 1965, 1970, 1975, 1980, 1985, 1990, 1995, 2000, 2005];

for (let i = 0; i < domain.length; i++) {
await page.evaluate(setSignal('anim_clock', i * 500));
await setSignal(view, 'anim_clock', i * 500);
await sleep(100);

const state = (await page.evaluate(getState(['anim_value'], ['source_0_curr']))) as {signals: any; data: any};
const anim_value = state.signals['anim_value'];
const anim_clock = await getState(view, ['anim_value'], ['source_0_curr']);
const anim_value = anim_clock.signals['anim_value'];

expect(anim_value).toBe(domain[i]);

const curr_dataset = state.data['source_0_curr'] as Datum[];
const curr_dataset = anim_clock.data['source_0_curr'] as Datum[];
const time_field = gapminderSpec.encoding.time.field as string;
const filteredDataset = curr_dataset.filter((d) => d[time_field] === anim_value);

expect(filteredDataset).toHaveLength(curr_dataset.length);

await testRender(`gapminder_${anim_value}`);
await expect(await view.toSVG()).toMatchFileSnapshot(`./snapshots/gapminder_${anim_value}.svg`);
}
}, 10000);

it('anim_clock makes forward progress', async () => {
await embed(gapminderSpec);
const view = await embed(gapminderSpec);

let anim_clock = (await page.evaluate(getSignal('anim_clock'))) as number;
let anim_clock = (await getSignal(view, 'anim_clock')) as number;
let prev_anim_clock = anim_clock;

for (let i = 0; i < 10; i++) {
await sleep(100);
anim_clock = (await page.evaluate(getSignal('anim_clock'))) as number;
anim_clock = (await getSignal(view, 'anim_clock')) as number;
expect(anim_clock).toBeGreaterThan(prev_anim_clock);
prev_anim_clock = anim_clock;
}
}, 10000);

it('anim_clock loops', async () => {
await embed(gapminderSpec);
const view = await embed(gapminderSpec);

const max_range_extent = (await page.evaluate(getSignal('max_range_extent'))) as number;
const max_range_extent = (await getSignal(view, 'max_range_extent')) as number;

await sleep(max_range_extent);

const anim_clock = await page.evaluate(getSignal('anim_clock'));
const anim_clock = (await getSignal(view, 'anim_clock')) as number;

expect(anim_clock).toBeLessThanOrEqual(max_range_extent);
}, 10000);
Expand Down
34 changes: 34 additions & 0 deletions test-runtime/basic.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import {describe, expect, it} from 'vitest';
import {TopLevelSpec} from '../src/index.js';
import {embed} from './util.js';

describe('Basic', () => {
it('should render a chart', async () => {
const spec: TopLevelSpec = {
mark: 'bar',
data: {
values: [
{a: 'A', b: 28},
{a: 'B', b: 55},
{a: 'C', b: 43},
{a: 'D', b: 91},
{a: 'E', b: 81},
{a: 'F', b: 53},
{a: 'G', b: 19},
{a: 'H', b: 87},
{a: 'I', b: 52},
],
},
encoding: {
x: {field: 'a'},
y: {field: 'b', type: 'quantitative'},
},
};

const view = await embed(spec);

const svg = await view.toSVG();

await expect(svg).toMatchFileSnapshot('./snapshots/basic.svg');
});
});
53 changes: 19 additions & 34 deletions test-runtime/discrete.test.ts
Original file line number Diff line number Diff line change
@@ -1,52 +1,37 @@
import {View} from 'vega';
import {SelectionType, SELECTION_ID} from '../src/selection.js';
import {embedFn, fill, hits as hitsMaster, pt, spec, testRenderFn} from './util.js';
import {Page} from 'puppeteer/lib/cjs/puppeteer/common/Page.js';
import {TopLevelSpec} from '../src/index.js';
import {embed, fill, hits as hitsMaster, pt, getSpec} from './util.js';
import {describe, expect, it} from 'vitest';

describe(`point selections at runtime in unit views`, () => {
let page: Page;
let embed: (specification: TopLevelSpec) => Promise<void>;
let testRender: (filename: string) => Promise<void>;

beforeAll(async () => {
page = await (global as any).__BROWSER_GLOBAL__.newPage();
embed = embedFn(page);
testRender = testRenderFn(page, `${type}/unit`);
await page.goto('http://0.0.0.0:9000/test-runtime/');
});

afterAll(async () => {
await page.close();
});

const type: SelectionType = 'point';
const hits = hitsMaster.discrete;

it('should add values to the store', async () => {
for (let i = 0; i < hits.qq.length; i++) {
await embed(spec('unit', i, {type}));
const store = (await page.evaluate(pt('qq', i))) as [any];
const view = await embed(getSpec('unit', i, {type}));
const store = (await pt(view, 'qq', i)) as [any];
expect(store).toHaveLength(1);
expect(store[0]).toHaveProperty(SELECTION_ID);
await testRender(`click_${i}`);
await expect(await view.toSVG()).toMatchFileSnapshot(`click_${i}`);
}
});

it('should respect projections', async () => {
let values: number[][] = [];
let encodings: string[] = [];
let fields: string[] = [];
const t = async (emb: (i: number) => void) => {
const t = async (emb: (i: number) => Promise<View>) => {
for (let i = 0; i < hits.qq.length; i++) {
emb(i);
const store = (await page.evaluate(pt('qq', i))) as [any];
const view = await emb(i);
const store = (await pt(view, 'qq', i)) as [any];
expect(store).toHaveLength(1);
expect(store[0].fields).toHaveLength(fields.length);
expect(store[0].values).toHaveLength(fields.length);
expect(store[0].fields.map((f: any) => f.field)).toEqual(fields);
expect(store[0].fields.map((f: any) => f.type)).toEqual(fill('E', fields.length));
expect(store[0].values).toEqual(values[i]);
await testRender(`${encodings}_${fields}_${i}`);
await expect(await view.toSVG()).toMatchFileSnapshot(`${encodings}_${fields}_${i}`);
}
};

Expand All @@ -56,26 +41,26 @@ describe(`point selections at runtime in unit views`, () => {
[2, 1],
[6, 0],
];
await t(async (i: number) => await embed(spec('unit', i, {type, encodings})));
await t(async (i: number) => await embed(getSpec('unit', i, {type, encodings})));

encodings = [];
fields = ['c', 'a', 'b'];
values = [
[1, 2, 53],
[0, 6, 87],
];
await t(async (i: number) => await embed(spec('unit', i, {type, fields})));
await t(async (i: number) => await embed(getSpec('unit', i, {type, fields})));
});

it('should clear out the store', async () => {
for (let i = 0; i < hits.qq_clear.length; i++) {
await embed(spec('unit', i, {type}));
let store = (await page.evaluate(pt('qq', i))) as [any];
const view = await embed(getSpec('unit', i, {type}));
let store = (await pt(view, 'qq', i)) as [any];
expect(store).toHaveLength(1);

store = (await page.evaluate(pt('qq_clear', i))) as [any];
store = (await pt(view, 'qq_clear', i)) as [any];
expect(store).toHaveLength(0);
await testRender(`clear_${i}`);
await expect(await view.toSVG()).toMatchFileSnapshot(`clear_${i}`);
}
});

Expand All @@ -89,15 +74,15 @@ describe(`point selections at runtime in unit views`, () => {
];

for (let i = 0; i < hits.bins.length; i++) {
await embed(spec('unit', i, {type, encodings}, {x: {bin: true}, y: {bin: true}}));
const store = (await page.evaluate(pt('bins', i))) as [any];
const view = await embed(getSpec('unit', i, {type, encodings}, {x: {bin: true}, y: {bin: true}}));
const store = (await pt(view, 'bins', i)) as [any];
expect(store).toHaveLength(1);
expect(store[0].fields).toHaveLength(fields.length);
expect(store[0].values).toHaveLength(fields.length);
expect(store[0].fields.map((f: any) => f.field)).toEqual(fields);
expect(store[0].fields.map((f: any) => f.type)).toEqual(types);
expect(store[0].values).toEqual(values[i]);
await testRender(`bins_${i}`);
await expect(await view.toSVG()).toMatchFileSnapshot(`bins_${i}`);
}
});
});
3 changes: 2 additions & 1 deletion test-runtime/interval.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import {TopLevelSpec} from '../src/index.js';
import {SelectionType} from '../src/selection.js';
import {brush, embedFn, geoSpec, hits as hitsMaster, spec, testRenderFn, tuples} from './util.js';
import {brush, embedFn, geoSpec, hits as hitsMaster, spec, testRenderFn, tuples} from './_util.js';
import {Page} from 'puppeteer/lib/cjs/puppeteer/common/Page.js';
import {describe, expect, it} from 'vitest';

describe('interval selections at runtime in unit views', () => {
let page: Page;
Expand Down
3 changes: 2 additions & 1 deletion test-runtime/resolve.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ import {
spec,
testRenderFn,
unitNameRegex,
} from './util.js';
} from './_util.js';
import {Page} from 'puppeteer/lib/cjs/puppeteer/common/Page.js';
import {TopLevelSpec} from '../src/index.js';
import {describe, expect, it} from 'vitest';

for (const type of selectionTypes) {
const isInterval = type === 'interval';
Expand Down
1 change: 1 addition & 0 deletions test-runtime/snapshots/basic.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion test-runtime/toggle.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import {stringValue} from 'vega-util';
import {TopLevelSpec} from '../src/index.js';
import {SelectionType} from '../src/selection.js';
import {compositeTypes, embedFn, parentSelector, spec, testRenderFn} from './util.js';
import {compositeTypes, embedFn, parentSelector, spec, testRenderFn} from './_util.js';
import {Page} from 'puppeteer/lib/cjs/puppeteer/common/Page.js';
import {describe, expect, it} from 'vitest';

const hits = {
qq: [8, 19, 13, 21],
Expand Down
3 changes: 2 additions & 1 deletion test-runtime/translate.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ import {
testRenderFn,
tuples,
unbound,
} from './util.js';
} from './_util.js';
import {Page} from 'puppeteer/lib/cjs/puppeteer/common/Page.js';
import {TopLevelSpec} from '../src/index.js';
import {describe, expect, it} from 'vitest';

describe('Translate interval selections at runtime', () => {
let page: Page;
Expand Down
Loading

0 comments on commit a9f0fb6

Please sign in to comment.