feat(editor): 新增 buildRunnableInfo 构造 runnable fence info string
纯函数,把语言+overrides 配置转成 'python runnable {...}' 形态。
dirty=false 省略 JSON,dirty=true 写 timeout/memory/network 三项,
字段顺序固定。
This commit is contained in:
parent
89bab26b90
commit
84b3da9db6
48
libs/tiptap-editor/src/__tests__/runnable-info.test.ts
Normal file
48
libs/tiptap-editor/src/__tests__/runnable-info.test.ts
Normal file
@ -0,0 +1,48 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { buildRunnableInfo } from '../slash-command';
|
||||
|
||||
/**
|
||||
* buildRunnableInfo 测试:把弹框收集的配置转成 fence info string。
|
||||
*
|
||||
* dirty=false(全默认) → 'python runnable'(省略 JSON)
|
||||
* dirty=true → 'python runnable {"timeout_secs":N,"memory_mb":M,"allow_network":B}'
|
||||
* JSON 字段顺序固定:timeout → memory → network
|
||||
*/
|
||||
|
||||
describe('buildRunnableInfo', () => {
|
||||
const base = {
|
||||
lang: 'python',
|
||||
timeoutSecs: 5,
|
||||
memoryMb: 256,
|
||||
allowNetwork: false,
|
||||
} as const;
|
||||
|
||||
describe('dirty=false(全默认,省略 JSON)', () => {
|
||||
it('python → "python runnable"', () => {
|
||||
expect(buildRunnableInfo({ ...base, dirty: false })).toBe('python runnable');
|
||||
});
|
||||
it('node → "node runnable"', () => {
|
||||
expect(buildRunnableInfo({ ...base, lang: 'node', dirty: false })).toBe('node runnable');
|
||||
});
|
||||
});
|
||||
|
||||
describe('dirty=true(写 JSON)', () => {
|
||||
it('改了 timeout,JSON 含全部 3 项', () => {
|
||||
expect(buildRunnableInfo({ ...base, timeoutSecs: 10, dirty: true })).toBe(
|
||||
'python runnable {"timeout_secs":10,"memory_mb":256,"allow_network":false}',
|
||||
);
|
||||
});
|
||||
it('node + 改了 allow_network', () => {
|
||||
expect(buildRunnableInfo({ ...base, lang: 'node', allowNetwork: true, dirty: true })).toBe(
|
||||
'node runnable {"timeout_secs":5,"memory_mb":256,"allow_network":true}',
|
||||
);
|
||||
});
|
||||
it('JSON 字段顺序固定(timeout→memory→network)', () => {
|
||||
const out = buildRunnableInfo({ ...base, dirty: true });
|
||||
const jsonStart = out.indexOf('{');
|
||||
const jsonEnd = out.lastIndexOf('}') + 1;
|
||||
const keys = Object.keys(JSON.parse(out.slice(jsonStart, jsonEnd)));
|
||||
expect(keys).toEqual(['timeout_secs', 'memory_mb', 'allow_network']);
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -363,3 +363,34 @@ function createPopup(props: SuggestionProps<CommandItem>): SlashPopup {
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/** buildRunnableInfo 的输入配置。 */
|
||||
export interface RunnableInfoOpts {
|
||||
/** 语言名(python / node)。 */
|
||||
lang: string;
|
||||
/** 超时秒数。 */
|
||||
timeoutSecs: number;
|
||||
/** 内存上限(MB)。 */
|
||||
memoryMb: number;
|
||||
/** 是否允许网络。 */
|
||||
allowNetwork: boolean;
|
||||
/** 作者是否改动过任一 overrides 字段;false 则省略 JSON。 */
|
||||
dirty: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* 把弹框收集的配置转成 markdown fence 的 info string。
|
||||
*
|
||||
* - dirty=false → `${lang} runnable`(省略 JSON,最小形态)
|
||||
* - dirty=true → `${lang} runnable {"timeout_secs":N,"memory_mb":M,"allow_network":B}`
|
||||
*
|
||||
* JSON 字段顺序固定(timeout → memory → network),由显式构造保证(不依赖对象插入顺序)。
|
||||
* 到达此函数时值必然合法(弹框「插入」按钮在非法值时 disabled)。
|
||||
*/
|
||||
export function buildRunnableInfo(opts: RunnableInfoOpts): string {
|
||||
const prefix = `${opts.lang} runnable`;
|
||||
if (!opts.dirty) return prefix;
|
||||
// 显式拼字符串,保证字段顺序固定(timeout → memory → network),不依赖对象键序。
|
||||
const json = `{"timeout_secs":${opts.timeoutSecs},"memory_mb":${opts.memoryMb},"allow_network":${opts.allowNetwork}}`;
|
||||
return `${prefix} ${json}`;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user