Skip to content
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
7 changes: 6 additions & 1 deletion .eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,12 @@ module.exports = {
},
overrides: [
{
files: ["tests/**/*.js", "apps/web/src/tests/jest/**/*.js"],
files: [
"tests/**/*.js",
"apps/**/*.test.js",
"apps/web/src/tests/jest/**/*.js",
"packages/*/src/tests/**/*.js",
],
env: {
jest: true,
node: true,
Expand Down
5 changes: 5 additions & 0 deletions apps/api/jest.config.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = {
testEnvironment: "node",
testMatch: ["<rootDir>/src/*.test.js"],
transform: {},
};
2 changes: 1 addition & 1 deletion apps/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"scripts": {
"build": "node -e \"console.log('api: no build step')\"",
"start": "node ./src/index.js",
"test": "node --test ./src/*.test.js"
"test": "node --experimental-vm-modules ../../node_modules/jest/bin/jest.js --config ./jest.config.cjs"
},
"dependencies": {
"@anywaydata/core": "^1.1.0",
Expand Down
18 changes: 8 additions & 10 deletions apps/api/src/docs.route.test.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
import test from 'node:test';
import assert from 'node:assert/strict';
import http from 'node:http';
import { app } from './index.js';

let server;
let port;

test.before(async () => {
beforeAll(async () => {
server = http.createServer(app);
await new Promise((resolve) => server.listen(0, resolve));
port = server.address().port;
});

test.after(async () => {
afterAll(async () => {
if (!server) {
return;
}
Expand All @@ -25,16 +23,16 @@ function url(path) {

test('/v1/openapi.json is available', async () => {
const response = await fetch(url('/v1/openapi.json'));
assert.equal(response.status, 200);
expect(response.status).toBe(200);
const body = await response.json();
assert.ok(body?.openapi);
assert.ok(body?.paths?.['/v1/generate']);
assert.ok(body?.paths?.['/v1/generate/options/{format}']);
expect(body?.openapi).toBeTruthy();
expect(body?.paths?.['/v1/generate']).toBeTruthy();
expect(body?.paths?.['/v1/generate/options/{format}']).toBeTruthy();
});

test('/v1/docs serves Swagger UI', async () => {
const response = await fetch(url('/v1/docs'));
assert.equal(response.status, 200);
expect(response.status).toBe(200);
const html = await response.text();
assert.match(html.toLowerCase(), /swagger/);
expect(html.toLowerCase()).toMatch(/swagger/);
});
52 changes: 25 additions & 27 deletions apps/api/src/fromschema.route.test.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
import test from 'node:test';
import assert from 'node:assert/strict';
import http from 'node:http';
import { app } from './index.js';

let server;
let port;

test.before(async () => {
beforeAll(async () => {
server = http.createServer(app);
await new Promise((resolve) => server.listen(0, resolve));
port = server.address().port;
});

test.after(async () => {
afterAll(async () => {
if (!server) {
return;
}
Expand All @@ -30,10 +28,10 @@ test('/v1/generate/fromschema defaults to rows response', async () => {
body: 'iata\nairline.airline.iataCode',
});

assert.equal(response.status, 200);
expect(response.status).toBe(200);
const body = await response.json();
assert.ok(Array.isArray(body.headers));
assert.ok(Array.isArray(body.rows));
expect(Array.isArray(body.headers)).toBeTruthy();
expect(Array.isArray(body.rows)).toBeTruthy();
});

test('/v1/generate/fromschema supports responseFormat=rendered', async () => {
Expand All @@ -43,9 +41,9 @@ test('/v1/generate/fromschema supports responseFormat=rendered', async () => {
body: 'iata\nairline.airline.iataCode',
});

assert.equal(response.status, 200);
expect(response.status).toBe(200);
const body = await response.json();
assert.equal(typeof body.rendered, 'string');
expect(typeof body.rendered).toBe('string');
});

test('/v1/generate/fromschema supports responseFormat=all', async () => {
Expand All @@ -55,10 +53,10 @@ test('/v1/generate/fromschema supports responseFormat=all', async () => {
body: 'iata\nairline.airline.iataCode',
});

assert.equal(response.status, 200);
expect(response.status).toBe(200);
const body = await response.json();
assert.ok(Array.isArray(body.rows));
assert.equal(typeof body.rendered, 'string');
expect(Array.isArray(body.rows)).toBeTruthy();
expect(typeof body.rendered).toBe('string');
});

test('/v1/generate/fromschema supports responseFormat=raw', async () => {
Expand All @@ -68,8 +66,8 @@ test('/v1/generate/fromschema supports responseFormat=raw', async () => {
body: 'iata\nairline.airline.iataCode',
});

assert.equal(response.status, 200);
assert.match(response.headers.get('content-type') || '', /text\/csv/i);
expect(response.status).toBe(200);
expect(response.headers.get('content-type') || '').toMatch(/text\/csv/i);
});

test('/v1/generate/fromschema rejects missing rowCount', async () => {
Expand All @@ -79,7 +77,7 @@ test('/v1/generate/fromschema rejects missing rowCount', async () => {
body: 'iata\nairline.airline.iataCode',
});

assert.equal(response.status, 400);
expect(response.status).toBe(400);
});

test('/v1/generate/fromschema rejects invalid responseFormat', async () => {
Expand All @@ -89,7 +87,7 @@ test('/v1/generate/fromschema rejects invalid responseFormat', async () => {
body: 'iata\nairline.airline.iataCode',
});

assert.equal(response.status, 400);
expect(response.status).toBe(400);
});

test('/v1/generate/fromschema rejects invalid outputFormat', async () => {
Expand All @@ -99,7 +97,7 @@ test('/v1/generate/fromschema rejects invalid outputFormat', async () => {
body: 'iata\nairline.airline.iataCode',
});

assert.equal(response.status, 400);
expect(response.status).toBe(400);
});

test('/v1/generate/fromschema accepts seed from query string and produces deterministic faker output', async () => {
Expand All @@ -110,12 +108,12 @@ test('/v1/generate/fromschema accepts seed from query string and produces determ
const responseA = await fetch(url(path), { method: 'POST', headers, body });
const responseB = await fetch(url(path), { method: 'POST', headers, body });

assert.equal(responseA.status, 200);
assert.equal(responseB.status, 200);
expect(responseA.status).toBe(200);
expect(responseB.status).toBe(200);

const payloadA = await responseA.json();
const payloadB = await responseB.json();
assert.deepEqual(payloadA.rows, payloadB.rows);
expect(payloadA.rows).toEqual(payloadB.rows);
});

test('/v1/generate/fromschema rejects invalid seed query value', async () => {
Expand All @@ -125,9 +123,9 @@ test('/v1/generate/fromschema rejects invalid seed query value', async () => {
body: 'iata\nairline.airline.iataCode',
});

assert.equal(response.status, 400);
expect(response.status).toBe(400);
const payload = await response.json();
assert.match(payload.errors?.[0] || '', /seed must be a finite number/i);
expect(payload.errors?.[0] || '').toMatch(/seed must be a finite number/i);
});

test('/v1/generate/fromschema applies unit-test defaults for includeSetup', async () => {
Expand All @@ -137,24 +135,24 @@ test('/v1/generate/fromschema applies unit-test defaults for includeSetup', asyn
headers: { 'content-type': 'application/json' },
body: JSON.stringify({ options: { includeSetup: true } }),
});
assert.equal(setDefaults.status, 200);
expect(setDefaults.status).toBe(200);

const response = await fetch(url('/v1/generate/fromschema?rowCount=1&outputFormat=jest&responseFormat=rendered'), {
method: 'POST',
headers: { 'content-type': 'text/plain' },
body: 'Name\nBob',
});

assert.equal(response.status, 200);
expect(response.status).toBe(200);
const body = await response.json();
assert.match(body.rendered, /beforeEach/);
assert.match(body.rendered, /expect\(/);
expect(body.rendered).toMatch(/beforeEach/);
expect(body.rendered).toMatch(/expect\(/);
} finally {
const resetDefaults = await fetch(url('/v1/generate/options/jest/default'), {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({}),
});
assert.equal(resetDefaults.status, 200);
expect(resetDefaults.status).toBe(200);
}
});
42 changes: 20 additions & 22 deletions apps/api/src/generate.route.test.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
import test from 'node:test';
import assert from 'node:assert/strict';
import http from 'node:http';
import { app } from './index.js';
import { generateFromTextSpec } from '@anywaydata/core';

let server;
let port;

test.before(async () => {
beforeAll(async () => {
server = http.createServer(app);
await new Promise((resolve) => server.listen(0, resolve));
port = server.address().port;
});

test.after(async () => {
afterAll(async () => {
if (!server) {
return;
}
Expand Down Expand Up @@ -45,11 +43,11 @@ test('/v1/generate returns rows payload for valid JSON request', async () => {
body: JSON.stringify({ textSpec: 'Name\nBob', rowCount: 1, outputFormat: 'json' }),
});

assert.equal(response.status, 200);
expect(response.status).toBe(200);
const body = await response.json();
assert.ok(Array.isArray(body.headers));
assert.ok(Array.isArray(body.rows));
assert.equal(Object.hasOwn(body, 'ok'), false);
expect(Array.isArray(body.headers)).toBeTruthy();
expect(Array.isArray(body.rows)).toBeTruthy();
expect(Object.hasOwn(body, 'ok')).toBe(false);
});

test('/v1/generate returns 400 + JSON diagnostics for invalid spec', async () => {
Expand All @@ -59,10 +57,10 @@ test('/v1/generate returns 400 + JSON diagnostics for invalid spec', async () =>
body: JSON.stringify({ textSpec: '', rowCount: 1, outputFormat: 'json' }),
});

assert.equal(response.status, 400);
expect(response.status).toBe(400);
const body = await response.json();
assert.ok(Array.isArray(body.errors));
assert.equal(typeof body.diagnostics, 'object');
expect(Array.isArray(body.errors)).toBeTruthy();
expect(typeof body.diagnostics).toBe('object');
});

test('/v1/generate returns JSON parse errors as JSON payload', async () => {
Expand All @@ -72,10 +70,10 @@ test('/v1/generate returns JSON parse errors as JSON payload', async () => {
body: '{"textSpec":"line1\nline2","rowCount":1,"outputFormat":"csv"}',
});

assert.equal(response.status, 400);
assert.match(response.headers.get('content-type') || '', /application\/json/i);
expect(response.status).toBe(400);
expect(response.headers.get('content-type') || '').toMatch(/application\/json/i);
const body = await response.json();
assert.ok(Array.isArray(body.errors));
expect(Array.isArray(body.errors)).toBeTruthy();
});

test('/v1/generate supports responseFormat=rendered', async () => {
Expand All @@ -85,10 +83,10 @@ test('/v1/generate supports responseFormat=rendered', async () => {
body: JSON.stringify({ textSpec: 'Name\nBob', rowCount: 1, outputFormat: 'json', responseFormat: 'rendered' }),
});

assert.equal(response.status, 200);
expect(response.status).toBe(200);
const body = await response.json();
assert.equal(typeof body.rendered, 'string');
assert.equal(Object.hasOwn(body, 'rows'), false);
expect(typeof body.rendered).toBe('string');
expect(Object.hasOwn(body, 'rows')).toBe(false);
});

test('/v1/generate supports responseFormat=raw', async () => {
Expand All @@ -98,8 +96,8 @@ test('/v1/generate supports responseFormat=raw', async () => {
body: JSON.stringify({ textSpec: 'Name\nBob', rowCount: 1, outputFormat: 'csv', responseFormat: 'raw' }),
});

assert.equal(response.status, 200);
assert.match(response.headers.get('content-type') || '', /text\/csv/i);
expect(response.status).toBe(200);
expect(response.headers.get('content-type') || '').toMatch(/text\/csv/i);
});

test('/v1/generate parity: REST rendered matches core for all unit-test frameworks', async () => {
Expand All @@ -118,7 +116,7 @@ test('/v1/generate parity: REST rendered matches core for all unit-test framewor
options,
seed: 123,
});
assert.equal(coreResult.ok, true, `core generation failed for ${outputFormat}`);
expect(coreResult.ok).toBe(true);

const response = await fetch(url('/v1/generate'), {
method: 'POST',
Expand All @@ -132,8 +130,8 @@ test('/v1/generate parity: REST rendered matches core for all unit-test framewor
seed: 123,
}),
});
assert.equal(response.status, 200, `api status failed for ${outputFormat}`);
expect(response.status).toBe(200);
const body = await response.json();
assert.equal(body.rendered, coreResult.rendered, `render mismatch for ${outputFormat}`);
expect(body.rendered).toBe(coreResult.rendered);
}
});
Loading
Loading