KAN-73: document and validate MCP ticket description format
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import { readFileSync } from 'node:fs';
|
||||
import process from 'node:process';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import vue from '@vitejs/plugin-vue';
|
||||
@@ -11,7 +12,24 @@ const serve = process.argv.includes('--serve');
|
||||
const server = await createServer({
|
||||
configFile: false,
|
||||
plugins: [vue(), ...(serve ? [tailwind()] : [])],
|
||||
optimizeDeps: {
|
||||
include: [
|
||||
'@tiptap/core',
|
||||
'@tiptap/pm/state',
|
||||
'@tiptap/vue-3',
|
||||
'@tiptap/markdown',
|
||||
'@tiptap/starter-kit',
|
||||
],
|
||||
},
|
||||
resolve: {
|
||||
dedupe: [
|
||||
'vue',
|
||||
'@tiptap/core',
|
||||
'@tiptap/pm',
|
||||
'prosemirror-state',
|
||||
'prosemirror-model',
|
||||
'prosemirror-view',
|
||||
],
|
||||
alias: {
|
||||
'@': fileURLToPath(new URL('../../resources/js', import.meta.url)),
|
||||
},
|
||||
@@ -56,6 +74,58 @@ if (serve) {
|
||||
renderToString(
|
||||
createSSRApp({ render: () => h(Description, { description }) }),
|
||||
);
|
||||
const cases = JSON.parse(
|
||||
readFileSync(
|
||||
new URL('./ticket-description-cases.json', import.meta.url),
|
||||
'utf8',
|
||||
),
|
||||
);
|
||||
const contract = JSON.parse(
|
||||
readFileSync(
|
||||
new URL(
|
||||
'../../resources/js/lib/ticket-description-format.json',
|
||||
import.meta.url,
|
||||
),
|
||||
'utf8',
|
||||
),
|
||||
);
|
||||
cases.push({
|
||||
name: 'MCP contract example',
|
||||
value: contract.example,
|
||||
supported: true,
|
||||
});
|
||||
for (const item of cases) {
|
||||
assert.equal(
|
||||
supportsVisualDescription(item.value),
|
||||
item.supported,
|
||||
item.name,
|
||||
);
|
||||
if (item.supported) {
|
||||
assert.ok(parseDescription(item.value));
|
||||
await render(item.value);
|
||||
}
|
||||
}
|
||||
if (process.argv.includes('--stored-description')) {
|
||||
const saved = JSON.parse(readFileSync(0, 'utf8'));
|
||||
assert.equal(supportsVisualDescription(saved.description), true);
|
||||
const html = await render(saved.description);
|
||||
assert.match(html, /<h2>Goal<\/h2>/);
|
||||
assert.match(html, /<strong>context<\/strong>/);
|
||||
assert.equal(
|
||||
parseDescription(saved.description).content[0].type,
|
||||
'heading',
|
||||
);
|
||||
for (const criterion of saved.criteria) {
|
||||
assert.ok(
|
||||
!html.includes(criterion.text),
|
||||
'Criteria stay in the separate checklist',
|
||||
);
|
||||
}
|
||||
}
|
||||
const exampleHtml = await render(contract.example);
|
||||
assert.match(exampleHtml, /<h2>Goal<\/h2>/);
|
||||
assert.match(exampleHtml, /<strong>context<\/strong>/);
|
||||
assert.doesNotMatch(exampleHtml, /acceptance_criteria|task checkboxes/);
|
||||
const markdown =
|
||||
'# Title\n\n**Bold** and *italic* and ~~strike~~\n\n- One\n - Nested\n\n3. Third\n4. Fourth\n\n> Quote\n\n`inline`\n\n```js\n<tag>\n```\n\n[Link](https://example.test/path)\n\n---';
|
||||
assert.equal(supportsVisualDescription(markdown), true);
|
||||
|
||||
Reference in New Issue
Block a user