testomatio-editor-blocks 0.4.76 → 0.4.77
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -379,7 +379,20 @@ function serializeBlock(block, ctx, orderedIndex, stepIndex) {
|
|
|
379
379
|
return lines;
|
|
380
380
|
}
|
|
381
381
|
lines.push(`<!-- ${kind}`);
|
|
382
|
-
fields.forEach((field) =>
|
|
382
|
+
fields.forEach((field) => {
|
|
383
|
+
// List-valued keys (e.g. `issues`) are written back as a YAML list to
|
|
384
|
+
// preserve the backend's format. The single panel field holds the items
|
|
385
|
+
// comma-separated, so split them back out into ` - item` lines.
|
|
386
|
+
if (LIST_META_KEYS.has(field.key.trim().toLowerCase())) {
|
|
387
|
+
const items = field.value.split(",").map((s) => s.trim()).filter(Boolean);
|
|
388
|
+
if (items.length) {
|
|
389
|
+
lines.push(`${field.key}:`);
|
|
390
|
+
items.forEach((item) => lines.push(` - ${item}`));
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
lines.push(`${field.key}: ${field.value}`);
|
|
395
|
+
});
|
|
383
396
|
lines.push("-->");
|
|
384
397
|
return lines;
|
|
385
398
|
}
|
|
@@ -1210,12 +1223,26 @@ function parseParagraph(lines, index) {
|
|
|
1210
1223
|
};
|
|
1211
1224
|
}
|
|
1212
1225
|
const META_COMMENT_OPEN_REGEX = /^<!--\s*(test|suite)(?=\s|-->|$)/i;
|
|
1226
|
+
// Keys whose value is a YAML-style list (`key:` followed by indented `- item`
|
|
1227
|
+
// lines) in the testomat.io comment format — e.g. `issues` holding URLs. These
|
|
1228
|
+
// round-trip back to a list on serialize; everything else stays a flat line.
|
|
1229
|
+
const LIST_META_KEYS = new Set(["issues"]);
|
|
1213
1230
|
function metaFieldsFromBody(bodyLines) {
|
|
1214
1231
|
const fields = [];
|
|
1215
1232
|
for (const raw of bodyLines) {
|
|
1216
1233
|
const line = raw.trim();
|
|
1217
1234
|
if (!line)
|
|
1218
1235
|
continue;
|
|
1236
|
+
// YAML list item: belongs to the most recent `key:` field. The whole item
|
|
1237
|
+
// (e.g. `https://github.com/...`) is kept verbatim — because we catch the
|
|
1238
|
+
// list line before the colon check, URLs with `://` are never split.
|
|
1239
|
+
if (line === "-" || line.startsWith("- ")) {
|
|
1240
|
+
const item = line.slice(1).trim();
|
|
1241
|
+
const current = fields[fields.length - 1];
|
|
1242
|
+
if (current && item)
|
|
1243
|
+
current.items.push(item);
|
|
1244
|
+
continue;
|
|
1245
|
+
}
|
|
1219
1246
|
const colon = line.indexOf(":");
|
|
1220
1247
|
// "Each line is `key: value`; lines without `:` are ignored."
|
|
1221
1248
|
if (colon === -1)
|
|
@@ -1224,9 +1251,13 @@ function metaFieldsFromBody(bodyLines) {
|
|
|
1224
1251
|
const value = line.slice(colon + 1).trim();
|
|
1225
1252
|
if (!key)
|
|
1226
1253
|
continue;
|
|
1227
|
-
fields.push({ key, value });
|
|
1254
|
+
fields.push({ key, value, items: [] });
|
|
1228
1255
|
}
|
|
1229
|
-
|
|
1256
|
+
// A field with collected list items → value is the items joined by ", ".
|
|
1257
|
+
return fields.map(({ key, value, items }) => ({
|
|
1258
|
+
key,
|
|
1259
|
+
value: items.length ? items.join(", ") : value,
|
|
1260
|
+
}));
|
|
1230
1261
|
}
|
|
1231
1262
|
function parseMetaComment(lines, index) {
|
|
1232
1263
|
const first = lines[index];
|
package/package.json
CHANGED
|
@@ -3223,6 +3223,77 @@ describe("test/suite metadata comments", () => {
|
|
|
3223
3223
|
expect(blocksToMarkdown(blocks as CustomEditorBlock[])).toBe(markdown);
|
|
3224
3224
|
});
|
|
3225
3225
|
|
|
3226
|
+
it("parses a YAML-list issues field without splitting URLs on ://", () => {
|
|
3227
|
+
const markdown = [
|
|
3228
|
+
"<!-- test",
|
|
3229
|
+
"id: @T4ffddec3",
|
|
3230
|
+
"type: manual",
|
|
3231
|
+
"issues:",
|
|
3232
|
+
" - https://github.com/testomatio/testomatio/issues/8963",
|
|
3233
|
+
"-->",
|
|
3234
|
+
].join("\n");
|
|
3235
|
+
const blocks = markdownToBlocks(markdown);
|
|
3236
|
+
expect((blocks[0].props as any).metaFields).toBe(
|
|
3237
|
+
JSON.stringify([
|
|
3238
|
+
{ key: "id", value: "@T4ffddec3" },
|
|
3239
|
+
{ key: "type", value: "manual" },
|
|
3240
|
+
{
|
|
3241
|
+
key: "issues",
|
|
3242
|
+
value: "https://github.com/testomatio/testomatio/issues/8963",
|
|
3243
|
+
},
|
|
3244
|
+
]),
|
|
3245
|
+
);
|
|
3246
|
+
});
|
|
3247
|
+
|
|
3248
|
+
it("joins multiple YAML-list issues items with a comma", () => {
|
|
3249
|
+
const markdown = [
|
|
3250
|
+
"<!-- test",
|
|
3251
|
+
"id: @T4ffddec3",
|
|
3252
|
+
"issues:",
|
|
3253
|
+
" - https://github.com/testomatio/testomatio/issues/8963",
|
|
3254
|
+
" - https://github.com/testomatio/testomatio/issues/9001",
|
|
3255
|
+
"-->",
|
|
3256
|
+
].join("\n");
|
|
3257
|
+
const blocks = markdownToBlocks(markdown);
|
|
3258
|
+
expect((blocks[0].props as any).metaFields).toBe(
|
|
3259
|
+
JSON.stringify([
|
|
3260
|
+
{ key: "id", value: "@T4ffddec3" },
|
|
3261
|
+
{
|
|
3262
|
+
key: "issues",
|
|
3263
|
+
value:
|
|
3264
|
+
"https://github.com/testomatio/testomatio/issues/8963, https://github.com/testomatio/testomatio/issues/9001",
|
|
3265
|
+
},
|
|
3266
|
+
]),
|
|
3267
|
+
);
|
|
3268
|
+
});
|
|
3269
|
+
|
|
3270
|
+
it("round-trips a YAML-list issues field (single item)", () => {
|
|
3271
|
+
const markdown = [
|
|
3272
|
+
"<!-- test",
|
|
3273
|
+
"id: @T4ffddec3",
|
|
3274
|
+
"type: manual",
|
|
3275
|
+
"priority: normal",
|
|
3276
|
+
"issues:",
|
|
3277
|
+
" - https://github.com/testomatio/testomatio/issues/8963",
|
|
3278
|
+
"-->",
|
|
3279
|
+
].join("\n");
|
|
3280
|
+
const blocks = markdownToBlocks(markdown);
|
|
3281
|
+
expect(blocksToMarkdown(blocks as CustomEditorBlock[])).toBe(markdown);
|
|
3282
|
+
});
|
|
3283
|
+
|
|
3284
|
+
it("round-trips a YAML-list issues field (multiple items)", () => {
|
|
3285
|
+
const markdown = [
|
|
3286
|
+
"<!-- test",
|
|
3287
|
+
"id: @T4ffddec3",
|
|
3288
|
+
"issues:",
|
|
3289
|
+
" - https://github.com/testomatio/testomatio/issues/8963",
|
|
3290
|
+
" - https://github.com/testomatio/testomatio/issues/9001",
|
|
3291
|
+
"-->",
|
|
3292
|
+
].join("\n");
|
|
3293
|
+
const blocks = markdownToBlocks(markdown);
|
|
3294
|
+
expect(blocksToMarkdown(blocks as CustomEditorBlock[])).toBe(markdown);
|
|
3295
|
+
});
|
|
3296
|
+
|
|
3226
3297
|
it("ignores lines without a colon inside a metadata block", () => {
|
|
3227
3298
|
const markdown = [
|
|
3228
3299
|
"<!-- test",
|
|
@@ -451,7 +451,20 @@ function serializeBlock(
|
|
|
451
451
|
}
|
|
452
452
|
|
|
453
453
|
lines.push(`<!-- ${kind}`);
|
|
454
|
-
fields.forEach((field) =>
|
|
454
|
+
fields.forEach((field) => {
|
|
455
|
+
// List-valued keys (e.g. `issues`) are written back as a YAML list to
|
|
456
|
+
// preserve the backend's format. The single panel field holds the items
|
|
457
|
+
// comma-separated, so split them back out into ` - item` lines.
|
|
458
|
+
if (LIST_META_KEYS.has(field.key.trim().toLowerCase())) {
|
|
459
|
+
const items = field.value.split(",").map((s) => s.trim()).filter(Boolean);
|
|
460
|
+
if (items.length) {
|
|
461
|
+
lines.push(`${field.key}:`);
|
|
462
|
+
items.forEach((item) => lines.push(` - ${item}`));
|
|
463
|
+
return;
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
lines.push(`${field.key}: ${field.value}`);
|
|
467
|
+
});
|
|
455
468
|
lines.push("-->");
|
|
456
469
|
return lines;
|
|
457
470
|
}
|
|
@@ -1422,20 +1435,41 @@ function parseParagraph(lines: string[], index: number): { block: CustomPartialB
|
|
|
1422
1435
|
|
|
1423
1436
|
const META_COMMENT_OPEN_REGEX = /^<!--\s*(test|suite)(?=\s|-->|$)/i;
|
|
1424
1437
|
|
|
1438
|
+
// Keys whose value is a YAML-style list (`key:` followed by indented `- item`
|
|
1439
|
+
// lines) in the testomat.io comment format — e.g. `issues` holding URLs. These
|
|
1440
|
+
// round-trip back to a list on serialize; everything else stays a flat line.
|
|
1441
|
+
const LIST_META_KEYS = new Set(["issues"]);
|
|
1442
|
+
|
|
1425
1443
|
function metaFieldsFromBody(bodyLines: string[]): { key: string; value: string }[] {
|
|
1426
|
-
const fields: { key: string; value: string }[] = [];
|
|
1444
|
+
const fields: { key: string; value: string; items: string[] }[] = [];
|
|
1427
1445
|
for (const raw of bodyLines) {
|
|
1428
1446
|
const line = raw.trim();
|
|
1429
1447
|
if (!line) continue;
|
|
1448
|
+
|
|
1449
|
+
// YAML list item: belongs to the most recent `key:` field. The whole item
|
|
1450
|
+
// (e.g. `https://github.com/...`) is kept verbatim — because we catch the
|
|
1451
|
+
// list line before the colon check, URLs with `://` are never split.
|
|
1452
|
+
if (line === "-" || line.startsWith("- ")) {
|
|
1453
|
+
const item = line.slice(1).trim();
|
|
1454
|
+
const current = fields[fields.length - 1];
|
|
1455
|
+
if (current && item) current.items.push(item);
|
|
1456
|
+
continue;
|
|
1457
|
+
}
|
|
1458
|
+
|
|
1430
1459
|
const colon = line.indexOf(":");
|
|
1431
1460
|
// "Each line is `key: value`; lines without `:` are ignored."
|
|
1432
1461
|
if (colon === -1) continue;
|
|
1433
1462
|
const key = line.slice(0, colon).trim();
|
|
1434
1463
|
const value = line.slice(colon + 1).trim();
|
|
1435
1464
|
if (!key) continue;
|
|
1436
|
-
fields.push({ key, value });
|
|
1465
|
+
fields.push({ key, value, items: [] });
|
|
1437
1466
|
}
|
|
1438
|
-
|
|
1467
|
+
|
|
1468
|
+
// A field with collected list items → value is the items joined by ", ".
|
|
1469
|
+
return fields.map(({ key, value, items }) => ({
|
|
1470
|
+
key,
|
|
1471
|
+
value: items.length ? items.join(", ") : value,
|
|
1472
|
+
}));
|
|
1439
1473
|
}
|
|
1440
1474
|
|
|
1441
1475
|
function parseMetaComment(
|