File size: 3,339 Bytes
76289e7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
import { describe, expect, it } from "vitest";
import { createPluginRecord } from "../plugins/loader-records.js";
import { createPluginRegistry } from "../plugins/registry.js";
import { createPluginRuntime } from "../plugins/runtime/index.js";

const report = "Backup completed successfully.";

describe("plugin newline chunk delivery", () => {
  it.each([
    {
      name: "does not overflow a full report with its terminating blank line",
      text: `${report}\n\n`,
      limit: 30,
      transportLimit: 30,
      expected: [report],
    },
    {
      name: "preserves a terminating blank line that fits",
      text: `${report}\n\n`,
      limit: 32,
      transportLimit: 32,
      expected: [`${report}\n\n`],
    },
    {
      name: "bounds the last report after earlier lines were delivered",
      text: `${report}\n${report}\n\n`,
      limit: 31,
      transportLimit: 31,
      expected: [report, `${report}\n`],
    },
    {
      name: "preserves ordinary blank lines between reports",
      text: `${report}\n\n${report}`,
      limit: 32,
      transportLimit: 32,
      expected: [report, `\n${report}`],
    },
    {
      name: "preserves an unsplit long line without adding excess blank lines",
      text: `${report}\n\n`,
      limit: 10,
      transportLimit: 30,
      options: { splitLongLines: false },
      expected: [report],
    },
    {
      name: "keeps an indivisible astral character without adding blank lines",
      text: "πŸ˜€\n\n",
      limit: 1,
      transportLimit: 2,
      expected: ["πŸ˜€"],
    },
    {
      name: "reserves a complete astral character after leading blank lines",
      text: "\nπŸ˜€",
      limit: 2,
      transportLimit: 2,
      expected: ["πŸ˜€"],
    },
    {
      name: "reserves a complete astral character after interior blank lines",
      text: "ok\n\nπŸ˜€",
      limit: 2,
      transportLimit: 2,
      expected: ["ok", "πŸ˜€"],
    },
  ])("$name", ({ text, limit, transportLimit, options, expected }) => {
    const accepted: string[] = [];
    const plugin = definePluginEntry({
      id: "newline-report-test",
      name: "Newline report test",
      description: "Exercises the injected text helper from a plugin entry.",
      register(api) {
        for (const chunk of api.runtime.channel.text.chunkByNewline(text, limit, options)) {
          // This transport is intentionally bounded independently of the chunker.
          // The long-line opt-out and indivisible-code-point cases use wider transports.
          if (chunk.length > transportLimit) {
            throw new Error(
              `Transport rejected ${chunk.length} UTF-16 units; limit ${transportLimit}`,
            );
          }
          accepted.push(chunk);
        }
      },
    });
    const registry = createPluginRegistry({
      runtime: createPluginRuntime(),
      logger: { info() {}, warn() {}, error() {} },
      activateGlobalSideEffects: false,
    });
    const record = createPluginRecord({
      id: plugin.id,
      source: "/virtual/newline-report-test/index.ts",
      origin: "global",
      enabled: true,
      configSchema: true,
    });
    const api = registry.createApi(record, { config: {} });

    plugin.register(api);

    expect(accepted).toEqual(expected);
  });
});