redscript-mc 1.2.30 → 2.0.0
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.
- package/.claude/commands/build-test.md +10 -0
- package/.claude/commands/deploy-demo.md +12 -0
- package/.claude/commands/stage-status.md +13 -0
- package/.claude/settings.json +12 -0
- package/.github/workflows/ci.yml +1 -0
- package/CLAUDE.md +231 -0
- package/demo.gif +0 -0
- package/dist/cli.js +2 -554
- package/dist/compile.js +2 -266
- package/dist/index.js +2 -159
- package/dist/lowering/index.js +5 -3
- package/dist/src/__tests__/cli.test.d.ts +1 -0
- package/dist/src/__tests__/cli.test.js +104 -0
- package/dist/src/__tests__/codegen.test.d.ts +1 -0
- package/dist/src/__tests__/codegen.test.js +152 -0
- package/dist/src/__tests__/compile-all.test.d.ts +10 -0
- package/dist/src/__tests__/compile-all.test.js +108 -0
- package/dist/src/__tests__/dce.test.d.ts +1 -0
- package/dist/src/__tests__/dce.test.js +102 -0
- package/dist/src/__tests__/diagnostics.test.d.ts +4 -0
- package/dist/src/__tests__/diagnostics.test.js +177 -0
- package/dist/src/__tests__/e2e.test.d.ts +6 -0
- package/dist/src/__tests__/e2e.test.js +1789 -0
- package/dist/src/__tests__/entity-types.test.d.ts +1 -0
- package/dist/src/__tests__/entity-types.test.js +203 -0
- package/dist/src/__tests__/formatter.test.d.ts +1 -0
- package/dist/src/__tests__/formatter.test.js +40 -0
- package/dist/src/__tests__/lexer.test.d.ts +1 -0
- package/dist/src/__tests__/lexer.test.js +343 -0
- package/dist/src/__tests__/lowering.test.d.ts +1 -0
- package/dist/src/__tests__/lowering.test.js +1015 -0
- package/dist/src/__tests__/macro.test.d.ts +8 -0
- package/dist/src/__tests__/macro.test.js +306 -0
- package/dist/src/__tests__/mc-integration.test.d.ts +12 -0
- package/dist/src/__tests__/mc-integration.test.js +817 -0
- package/dist/src/__tests__/mc-syntax.test.d.ts +1 -0
- package/dist/src/__tests__/mc-syntax.test.js +124 -0
- package/dist/src/__tests__/nbt.test.d.ts +1 -0
- package/dist/src/__tests__/nbt.test.js +82 -0
- package/dist/src/__tests__/optimizer-advanced.test.d.ts +1 -0
- package/dist/src/__tests__/optimizer-advanced.test.js +124 -0
- package/dist/src/__tests__/optimizer.test.d.ts +1 -0
- package/dist/src/__tests__/optimizer.test.js +149 -0
- package/dist/src/__tests__/parser.test.d.ts +1 -0
- package/dist/src/__tests__/parser.test.js +807 -0
- package/dist/src/__tests__/repl.test.d.ts +1 -0
- package/dist/src/__tests__/repl.test.js +27 -0
- package/dist/src/__tests__/runtime.test.d.ts +1 -0
- package/dist/src/__tests__/runtime.test.js +289 -0
- package/dist/src/__tests__/stdlib-advanced.test.d.ts +4 -0
- package/dist/src/__tests__/stdlib-advanced.test.js +374 -0
- package/dist/src/__tests__/stdlib-bigint.test.d.ts +7 -0
- package/dist/src/__tests__/stdlib-bigint.test.js +426 -0
- package/dist/src/__tests__/stdlib-math.test.d.ts +7 -0
- package/dist/src/__tests__/stdlib-math.test.js +351 -0
- package/dist/src/__tests__/stdlib-vec.test.d.ts +4 -0
- package/dist/src/__tests__/stdlib-vec.test.js +263 -0
- package/dist/src/__tests__/structure-optimizer.test.d.ts +1 -0
- package/dist/src/__tests__/structure-optimizer.test.js +33 -0
- package/dist/src/__tests__/typechecker.test.d.ts +1 -0
- package/dist/src/__tests__/typechecker.test.js +552 -0
- package/dist/src/__tests__/var-allocator.test.d.ts +1 -0
- package/dist/src/__tests__/var-allocator.test.js +69 -0
- package/dist/src/ast/types.d.ts +515 -0
- package/dist/src/ast/types.js +9 -0
- package/dist/src/builtins/metadata.d.ts +36 -0
- package/dist/src/builtins/metadata.js +1014 -0
- package/dist/src/cli.d.ts +11 -0
- package/dist/src/cli.js +443 -0
- package/dist/src/codegen/cmdblock/index.d.ts +26 -0
- package/dist/src/codegen/cmdblock/index.js +45 -0
- package/dist/src/codegen/mcfunction/index.d.ts +40 -0
- package/dist/src/codegen/mcfunction/index.js +606 -0
- package/dist/src/codegen/structure/index.d.ts +24 -0
- package/dist/src/codegen/structure/index.js +279 -0
- package/dist/src/codegen/var-allocator.d.ts +45 -0
- package/dist/src/codegen/var-allocator.js +104 -0
- package/dist/src/compile.d.ts +37 -0
- package/dist/src/compile.js +165 -0
- package/dist/src/diagnostics/index.d.ts +44 -0
- package/dist/src/diagnostics/index.js +140 -0
- package/dist/src/events/types.d.ts +35 -0
- package/dist/src/events/types.js +59 -0
- package/dist/src/formatter/index.d.ts +1 -0
- package/dist/src/formatter/index.js +26 -0
- package/dist/src/index.d.ts +22 -0
- package/dist/src/index.js +45 -0
- package/dist/src/ir/builder.d.ts +33 -0
- package/dist/src/ir/builder.js +99 -0
- package/dist/src/ir/types.d.ts +132 -0
- package/dist/src/ir/types.js +15 -0
- package/dist/src/lexer/index.d.ts +37 -0
- package/dist/src/lexer/index.js +569 -0
- package/dist/src/lowering/index.d.ts +188 -0
- package/dist/src/lowering/index.js +3405 -0
- package/dist/src/mc-test/client.d.ts +128 -0
- package/dist/src/mc-test/client.js +174 -0
- package/dist/src/mc-test/runner.d.ts +28 -0
- package/dist/src/mc-test/runner.js +151 -0
- package/dist/src/mc-test/setup.d.ts +11 -0
- package/dist/src/mc-test/setup.js +98 -0
- package/dist/src/mc-validator/index.d.ts +17 -0
- package/dist/src/mc-validator/index.js +322 -0
- package/dist/src/nbt/index.d.ts +86 -0
- package/dist/src/nbt/index.js +250 -0
- package/dist/src/optimizer/commands.d.ts +38 -0
- package/dist/src/optimizer/commands.js +451 -0
- package/dist/src/optimizer/dce.d.ts +34 -0
- package/dist/src/optimizer/dce.js +639 -0
- package/dist/src/optimizer/passes.d.ts +34 -0
- package/dist/src/optimizer/passes.js +243 -0
- package/dist/src/optimizer/structure.d.ts +9 -0
- package/dist/src/optimizer/structure.js +356 -0
- package/dist/src/parser/index.d.ts +93 -0
- package/dist/src/parser/index.js +1687 -0
- package/dist/src/repl.d.ts +16 -0
- package/dist/src/repl.js +165 -0
- package/dist/src/runtime/index.d.ts +107 -0
- package/dist/src/runtime/index.js +1409 -0
- package/dist/src/typechecker/index.d.ts +61 -0
- package/dist/src/typechecker/index.js +1034 -0
- package/dist/src/types/entity-hierarchy.d.ts +29 -0
- package/dist/src/types/entity-hierarchy.js +107 -0
- package/dist/src2/__tests__/e2e/basic.test.d.ts +8 -0
- package/dist/src2/__tests__/e2e/basic.test.js +140 -0
- package/dist/src2/__tests__/e2e/macros.test.d.ts +9 -0
- package/dist/src2/__tests__/e2e/macros.test.js +182 -0
- package/dist/src2/__tests__/e2e/migrate.test.d.ts +13 -0
- package/dist/src2/__tests__/e2e/migrate.test.js +2739 -0
- package/dist/src2/__tests__/hir/desugar.test.d.ts +1 -0
- package/dist/src2/__tests__/hir/desugar.test.js +234 -0
- package/dist/src2/__tests__/lir/lower.test.d.ts +1 -0
- package/dist/src2/__tests__/lir/lower.test.js +559 -0
- package/dist/src2/__tests__/lir/types.test.d.ts +1 -0
- package/dist/src2/__tests__/lir/types.test.js +185 -0
- package/dist/src2/__tests__/lir/verify.test.d.ts +1 -0
- package/dist/src2/__tests__/lir/verify.test.js +221 -0
- package/dist/src2/__tests__/mir/arithmetic.test.d.ts +1 -0
- package/dist/src2/__tests__/mir/arithmetic.test.js +130 -0
- package/dist/src2/__tests__/mir/control-flow.test.d.ts +1 -0
- package/dist/src2/__tests__/mir/control-flow.test.js +205 -0
- package/dist/src2/__tests__/mir/verify.test.d.ts +1 -0
- package/dist/src2/__tests__/mir/verify.test.js +223 -0
- package/dist/src2/__tests__/optimizer/block_merge.test.d.ts +1 -0
- package/dist/src2/__tests__/optimizer/block_merge.test.js +78 -0
- package/dist/src2/__tests__/optimizer/branch_simplify.test.d.ts +1 -0
- package/dist/src2/__tests__/optimizer/branch_simplify.test.js +58 -0
- package/dist/src2/__tests__/optimizer/constant_fold.test.d.ts +1 -0
- package/dist/src2/__tests__/optimizer/constant_fold.test.js +131 -0
- package/dist/src2/__tests__/optimizer/copy_prop.test.d.ts +1 -0
- package/dist/src2/__tests__/optimizer/copy_prop.test.js +91 -0
- package/dist/src2/__tests__/optimizer/dce.test.d.ts +1 -0
- package/dist/src2/__tests__/optimizer/dce.test.js +76 -0
- package/dist/src2/__tests__/optimizer/pipeline.test.d.ts +1 -0
- package/dist/src2/__tests__/optimizer/pipeline.test.js +102 -0
- package/dist/src2/emit/compile.d.ts +19 -0
- package/dist/src2/emit/compile.js +80 -0
- package/dist/src2/emit/index.d.ts +17 -0
- package/dist/src2/emit/index.js +172 -0
- package/dist/src2/hir/lower.d.ts +15 -0
- package/dist/src2/hir/lower.js +378 -0
- package/dist/src2/hir/types.d.ts +373 -0
- package/dist/src2/hir/types.js +16 -0
- package/dist/src2/lir/lower.d.ts +15 -0
- package/dist/src2/lir/lower.js +453 -0
- package/dist/src2/lir/types.d.ts +136 -0
- package/dist/src2/lir/types.js +11 -0
- package/dist/src2/lir/verify.d.ts +14 -0
- package/dist/src2/lir/verify.js +113 -0
- package/dist/src2/mir/lower.d.ts +9 -0
- package/dist/src2/mir/lower.js +1030 -0
- package/dist/src2/mir/macro.d.ts +22 -0
- package/dist/src2/mir/macro.js +168 -0
- package/dist/src2/mir/types.d.ts +183 -0
- package/dist/src2/mir/types.js +11 -0
- package/dist/src2/mir/verify.d.ts +16 -0
- package/dist/src2/mir/verify.js +216 -0
- package/dist/src2/optimizer/block_merge.d.ts +12 -0
- package/dist/src2/optimizer/block_merge.js +84 -0
- package/dist/src2/optimizer/branch_simplify.d.ts +9 -0
- package/dist/src2/optimizer/branch_simplify.js +28 -0
- package/dist/src2/optimizer/constant_fold.d.ts +10 -0
- package/dist/src2/optimizer/constant_fold.js +85 -0
- package/dist/src2/optimizer/copy_prop.d.ts +9 -0
- package/dist/src2/optimizer/copy_prop.js +113 -0
- package/dist/src2/optimizer/dce.d.ts +8 -0
- package/dist/src2/optimizer/dce.js +155 -0
- package/dist/src2/optimizer/pipeline.d.ts +10 -0
- package/dist/src2/optimizer/pipeline.js +42 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/docs/compiler-pipeline-redesign.md +2243 -0
- package/docs/optimization-ideas.md +1076 -0
- package/editors/vscode/package-lock.json +3 -3
- package/editors/vscode/package.json +1 -1
- package/jest.config.js +1 -1
- package/package.json +6 -5
- package/scripts/postbuild.js +15 -0
- package/src/__tests__/cli.test.ts +8 -220
- package/src/__tests__/dce.test.ts +11 -56
- package/src/__tests__/diagnostics.test.ts +59 -38
- package/src/__tests__/mc-integration.test.ts +1 -2
- package/src/ast/types.ts +6 -1
- package/src/cli.ts +29 -156
- package/src/compile.ts +6 -162
- package/src/index.ts +14 -178
- package/src/mc-test/runner.ts +4 -3
- package/src/parser/index.ts +1 -1
- package/src/repl.ts +1 -1
- package/src/runtime/index.ts +1 -1
- package/src2/__tests__/e2e/basic.test.ts +154 -0
- package/src2/__tests__/e2e/macros.test.ts +199 -0
- package/src2/__tests__/e2e/migrate.test.ts +3008 -0
- package/src2/__tests__/hir/desugar.test.ts +263 -0
- package/src2/__tests__/lir/lower.test.ts +619 -0
- package/src2/__tests__/lir/types.test.ts +207 -0
- package/src2/__tests__/lir/verify.test.ts +249 -0
- package/src2/__tests__/mir/arithmetic.test.ts +156 -0
- package/src2/__tests__/mir/control-flow.test.ts +242 -0
- package/src2/__tests__/mir/verify.test.ts +254 -0
- package/src2/__tests__/optimizer/block_merge.test.ts +84 -0
- package/src2/__tests__/optimizer/branch_simplify.test.ts +64 -0
- package/src2/__tests__/optimizer/constant_fold.test.ts +145 -0
- package/src2/__tests__/optimizer/copy_prop.test.ts +99 -0
- package/src2/__tests__/optimizer/dce.test.ts +83 -0
- package/src2/__tests__/optimizer/pipeline.test.ts +116 -0
- package/src2/emit/compile.ts +99 -0
- package/src2/emit/index.ts +222 -0
- package/src2/hir/lower.ts +428 -0
- package/src2/hir/types.ts +216 -0
- package/src2/lir/lower.ts +556 -0
- package/src2/lir/types.ts +109 -0
- package/src2/lir/verify.ts +129 -0
- package/src2/mir/lower.ts +1160 -0
- package/src2/mir/macro.ts +167 -0
- package/src2/mir/types.ts +106 -0
- package/src2/mir/verify.ts +218 -0
- package/src2/optimizer/block_merge.ts +93 -0
- package/src2/optimizer/branch_simplify.ts +27 -0
- package/src2/optimizer/constant_fold.ts +88 -0
- package/src2/optimizer/copy_prop.ts +106 -0
- package/src2/optimizer/dce.ts +133 -0
- package/src2/optimizer/pipeline.ts +44 -0
- package/tsconfig.json +2 -2
- package/src/__tests__/codegen.test.ts +0 -161
- package/src/__tests__/e2e.test.ts +0 -2039
- package/src/__tests__/entity-types.test.ts +0 -236
- package/src/__tests__/lowering.test.ts +0 -1185
- package/src/__tests__/macro.test.ts +0 -343
- package/src/__tests__/nbt.test.ts +0 -58
- package/src/__tests__/optimizer-advanced.test.ts +0 -144
- package/src/__tests__/optimizer.test.ts +0 -162
- package/src/__tests__/runtime.test.ts +0 -305
- package/src/__tests__/stdlib-advanced.test.ts +0 -379
- package/src/__tests__/stdlib-bigint.test.ts +0 -427
- package/src/__tests__/stdlib-math.test.ts +0 -374
- package/src/__tests__/stdlib-vec.test.ts +0 -259
- package/src/__tests__/structure-optimizer.test.ts +0 -38
- package/src/__tests__/var-allocator.test.ts +0 -75
- package/src/codegen/cmdblock/index.ts +0 -63
- package/src/codegen/mcfunction/index.ts +0 -662
- package/src/codegen/structure/index.ts +0 -346
- package/src/codegen/var-allocator.ts +0 -104
- package/src/ir/builder.ts +0 -116
- package/src/ir/types.ts +0 -134
- package/src/lowering/index.ts +0 -3876
- package/src/optimizer/commands.ts +0 -534
- package/src/optimizer/dce.ts +0 -679
- package/src/optimizer/passes.ts +0 -250
- package/src/optimizer/structure.ts +0 -450
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RedScript MC Test Client
|
|
3
|
+
*
|
|
4
|
+
* Connects to a Paper server running TestHarnessPlugin and provides
|
|
5
|
+
* a fluent API for integration testing compiled datapacks.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* const mc = new MCTestClient('localhost', 25561)
|
|
9
|
+
* await mc.command('/function arena:start')
|
|
10
|
+
* await mc.ticks(100)
|
|
11
|
+
* const score = await mc.scoreboard('Alice', 'kills')
|
|
12
|
+
* expect(score).toBe(3)
|
|
13
|
+
*/
|
|
14
|
+
export interface ScoreResult {
|
|
15
|
+
player: string;
|
|
16
|
+
obj: string;
|
|
17
|
+
value: number;
|
|
18
|
+
}
|
|
19
|
+
export interface BlockResult {
|
|
20
|
+
x: number;
|
|
21
|
+
y: number;
|
|
22
|
+
z: number;
|
|
23
|
+
world: string;
|
|
24
|
+
type: string;
|
|
25
|
+
blockData: string;
|
|
26
|
+
}
|
|
27
|
+
export interface EntityResult {
|
|
28
|
+
uuid: string;
|
|
29
|
+
name: string;
|
|
30
|
+
type: string;
|
|
31
|
+
x: number;
|
|
32
|
+
y: number;
|
|
33
|
+
z: number;
|
|
34
|
+
world: string;
|
|
35
|
+
tags: string[];
|
|
36
|
+
}
|
|
37
|
+
export interface ChatMessage {
|
|
38
|
+
tick: number;
|
|
39
|
+
type: string;
|
|
40
|
+
sender?: string;
|
|
41
|
+
message: string;
|
|
42
|
+
}
|
|
43
|
+
export interface GameEvent {
|
|
44
|
+
tick: number;
|
|
45
|
+
type: string;
|
|
46
|
+
player?: string;
|
|
47
|
+
advancement?: string;
|
|
48
|
+
cause?: string;
|
|
49
|
+
}
|
|
50
|
+
export interface ServerStatus {
|
|
51
|
+
online: boolean;
|
|
52
|
+
tps_1m: number;
|
|
53
|
+
tps_5m: number;
|
|
54
|
+
tps_15m: number;
|
|
55
|
+
players: number;
|
|
56
|
+
playerNames: string[];
|
|
57
|
+
worlds: string[];
|
|
58
|
+
version: string;
|
|
59
|
+
}
|
|
60
|
+
export declare class MCTestClient {
|
|
61
|
+
private baseUrl;
|
|
62
|
+
constructor(host?: string, port?: number);
|
|
63
|
+
private get;
|
|
64
|
+
private post;
|
|
65
|
+
/** Check if server is reachable */
|
|
66
|
+
isOnline(): Promise<boolean>;
|
|
67
|
+
/** Get server status */
|
|
68
|
+
status(): Promise<ServerStatus>;
|
|
69
|
+
/** Run a command on the server (as console sender) */
|
|
70
|
+
command(cmd: string): Promise<{
|
|
71
|
+
ok: boolean;
|
|
72
|
+
cmd: string;
|
|
73
|
+
}>;
|
|
74
|
+
/** Wait for N server ticks (50ms each) */
|
|
75
|
+
ticks(count: number): Promise<void>;
|
|
76
|
+
/** Wait for 1 second = 20 ticks */
|
|
77
|
+
seconds(s: number): Promise<void>;
|
|
78
|
+
/** Get a scoreboard value */
|
|
79
|
+
scoreboard(player: string, obj: string): Promise<number>;
|
|
80
|
+
/** Get all scoreboard values for a selector */
|
|
81
|
+
scoreboardAll(selector: string, obj: string): Promise<ScoreResult[]>;
|
|
82
|
+
/** Get block at position */
|
|
83
|
+
block(x: number, y: number, z: number, world?: string): Promise<BlockResult>;
|
|
84
|
+
/** Get entities matching selector */
|
|
85
|
+
entities(selector?: string): Promise<EntityResult[]>;
|
|
86
|
+
/** Get chat log since a tick */
|
|
87
|
+
chat(since?: number): Promise<ChatMessage[]>;
|
|
88
|
+
/** Get last N chat messages */
|
|
89
|
+
chatLast(n: number): Promise<ChatMessage[]>;
|
|
90
|
+
/** Get events since a tick, optionally filtered by type */
|
|
91
|
+
events(since?: number, type?: string): Promise<GameEvent[]>;
|
|
92
|
+
/** Clear chat and event logs */
|
|
93
|
+
reset(): Promise<void>;
|
|
94
|
+
/**
|
|
95
|
+
* Full test reset: clear logs + fill test area with air + kill entities + reset scoreboards.
|
|
96
|
+
* Call this at the start of each integration test.
|
|
97
|
+
*/
|
|
98
|
+
fullReset(options?: {
|
|
99
|
+
x1?: number;
|
|
100
|
+
y1?: number;
|
|
101
|
+
z1?: number;
|
|
102
|
+
x2?: number;
|
|
103
|
+
y2?: number;
|
|
104
|
+
z2?: number;
|
|
105
|
+
clearArea?: boolean;
|
|
106
|
+
killEntities?: boolean;
|
|
107
|
+
resetScoreboards?: boolean;
|
|
108
|
+
}): Promise<void>;
|
|
109
|
+
/** Reload datapacks */
|
|
110
|
+
reload(): Promise<void>;
|
|
111
|
+
/**
|
|
112
|
+
* Assert a scoreboard value equals expected.
|
|
113
|
+
* Throws with a descriptive error if it doesn't match.
|
|
114
|
+
*/
|
|
115
|
+
assertScore(player: string, obj: string, expected: number, msg?: string): Promise<void>;
|
|
116
|
+
/**
|
|
117
|
+
* Assert a block type at position.
|
|
118
|
+
*/
|
|
119
|
+
assertBlock(x: number, y: number, z: number, expectedType: string, world?: string): Promise<void>;
|
|
120
|
+
/**
|
|
121
|
+
* Assert chat log contains a message matching substring.
|
|
122
|
+
*/
|
|
123
|
+
assertChatContains(substring: string, since?: number): Promise<void>;
|
|
124
|
+
/**
|
|
125
|
+
* Wait until a scoreboard value equals expected, up to timeout ms.
|
|
126
|
+
*/
|
|
127
|
+
waitForScore(player: string, obj: string, expected: number, timeoutMs?: number, pollMs?: number): Promise<void>;
|
|
128
|
+
}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* RedScript MC Test Client
|
|
4
|
+
*
|
|
5
|
+
* Connects to a Paper server running TestHarnessPlugin and provides
|
|
6
|
+
* a fluent API for integration testing compiled datapacks.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* const mc = new MCTestClient('localhost', 25561)
|
|
10
|
+
* await mc.command('/function arena:start')
|
|
11
|
+
* await mc.ticks(100)
|
|
12
|
+
* const score = await mc.scoreboard('Alice', 'kills')
|
|
13
|
+
* expect(score).toBe(3)
|
|
14
|
+
*/
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.MCTestClient = void 0;
|
|
17
|
+
class MCTestClient {
|
|
18
|
+
constructor(host = 'localhost', port = 25561) {
|
|
19
|
+
this.baseUrl = `http://${host}:${port}`;
|
|
20
|
+
}
|
|
21
|
+
async get(path, params = {}) {
|
|
22
|
+
const qs = Object.entries(params)
|
|
23
|
+
.map(([k, v]) => `${k}=${encodeURIComponent(String(v))}`)
|
|
24
|
+
.join('&');
|
|
25
|
+
const url = `${this.baseUrl}${path}${qs ? '?' + qs : ''}`;
|
|
26
|
+
const res = await fetch(url);
|
|
27
|
+
if (!res.ok) {
|
|
28
|
+
const body = await res.text();
|
|
29
|
+
throw new Error(`GET ${path} failed ${res.status}: ${body}`);
|
|
30
|
+
}
|
|
31
|
+
return res.json();
|
|
32
|
+
}
|
|
33
|
+
async post(path, body = {}) {
|
|
34
|
+
const res = await fetch(`${this.baseUrl}${path}`, {
|
|
35
|
+
method: 'POST',
|
|
36
|
+
headers: { 'Content-Type': 'application/json' },
|
|
37
|
+
body: JSON.stringify(body)
|
|
38
|
+
});
|
|
39
|
+
if (!res.ok) {
|
|
40
|
+
const text = await res.text();
|
|
41
|
+
throw new Error(`POST ${path} failed ${res.status}: ${text}`);
|
|
42
|
+
}
|
|
43
|
+
return res.json();
|
|
44
|
+
}
|
|
45
|
+
/** Check if server is reachable */
|
|
46
|
+
async isOnline() {
|
|
47
|
+
try {
|
|
48
|
+
const status = await this.get('/status');
|
|
49
|
+
return status.online;
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/** Get server status */
|
|
56
|
+
async status() {
|
|
57
|
+
return this.get('/status');
|
|
58
|
+
}
|
|
59
|
+
/** Run a command on the server (as console sender) */
|
|
60
|
+
async command(cmd) {
|
|
61
|
+
return this.post('/command', { cmd });
|
|
62
|
+
}
|
|
63
|
+
/** Wait for N server ticks (50ms each) */
|
|
64
|
+
async ticks(count) {
|
|
65
|
+
await this.post('/tick', { count });
|
|
66
|
+
}
|
|
67
|
+
/** Wait for 1 second = 20 ticks */
|
|
68
|
+
async seconds(s) {
|
|
69
|
+
await this.ticks(s * 20);
|
|
70
|
+
}
|
|
71
|
+
/** Get a scoreboard value */
|
|
72
|
+
async scoreboard(player, obj) {
|
|
73
|
+
const result = await this.get('/scoreboard', { player, obj });
|
|
74
|
+
return result.value;
|
|
75
|
+
}
|
|
76
|
+
/** Get all scoreboard values for a selector */
|
|
77
|
+
async scoreboardAll(selector, obj) {
|
|
78
|
+
return this.get('/scoreboard', { player: selector, obj });
|
|
79
|
+
}
|
|
80
|
+
/** Get block at position */
|
|
81
|
+
async block(x, y, z, world = 'world') {
|
|
82
|
+
return this.get('/block', { x, y, z, world });
|
|
83
|
+
}
|
|
84
|
+
/** Get entities matching selector */
|
|
85
|
+
async entities(selector = '@e') {
|
|
86
|
+
return this.get('/entity', { sel: selector });
|
|
87
|
+
}
|
|
88
|
+
/** Get chat log since a tick */
|
|
89
|
+
async chat(since = 0) {
|
|
90
|
+
return this.get('/chat', { since });
|
|
91
|
+
}
|
|
92
|
+
/** Get last N chat messages */
|
|
93
|
+
async chatLast(n) {
|
|
94
|
+
return this.get('/chat', { last: n });
|
|
95
|
+
}
|
|
96
|
+
/** Get events since a tick, optionally filtered by type */
|
|
97
|
+
async events(since = 0, type) {
|
|
98
|
+
const params = { since };
|
|
99
|
+
if (type)
|
|
100
|
+
params.type = type;
|
|
101
|
+
return this.get('/events', params);
|
|
102
|
+
}
|
|
103
|
+
/** Clear chat and event logs */
|
|
104
|
+
async reset() {
|
|
105
|
+
await this.post('/reset');
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Full test reset: clear logs + fill test area with air + kill entities + reset scoreboards.
|
|
109
|
+
* Call this at the start of each integration test.
|
|
110
|
+
*/
|
|
111
|
+
async fullReset(options) {
|
|
112
|
+
await this.post('/reset', {
|
|
113
|
+
clearArea: options?.clearArea ?? true,
|
|
114
|
+
killEntities: options?.killEntities ?? true,
|
|
115
|
+
resetScoreboards: options?.resetScoreboards ?? true,
|
|
116
|
+
x1: options?.x1 ?? -50, y1: options?.y1 ?? 0, z1: options?.z1 ?? -50,
|
|
117
|
+
x2: options?.x2 ?? 50, y2: options?.y2 ?? 100, z2: options?.z2 ?? 50,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
/** Reload datapacks */
|
|
121
|
+
async reload() {
|
|
122
|
+
await this.post('/reload');
|
|
123
|
+
await this.ticks(40); // wait 2s for reload
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Assert a scoreboard value equals expected.
|
|
127
|
+
* Throws with a descriptive error if it doesn't match.
|
|
128
|
+
*/
|
|
129
|
+
async assertScore(player, obj, expected, msg) {
|
|
130
|
+
const actual = await this.scoreboard(player, obj);
|
|
131
|
+
if (actual !== expected) {
|
|
132
|
+
throw new Error(msg ?? `assertScore failed: ${player}/${obj} expected ${expected}, got ${actual}`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Assert a block type at position.
|
|
137
|
+
*/
|
|
138
|
+
async assertBlock(x, y, z, expectedType, world = 'world') {
|
|
139
|
+
const block = await this.block(x, y, z, world);
|
|
140
|
+
if (block.type !== expectedType) {
|
|
141
|
+
throw new Error(`assertBlock failed: (${x},${y},${z}) expected ${expectedType}, got ${block.type}`);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Assert chat log contains a message matching substring.
|
|
146
|
+
*/
|
|
147
|
+
async assertChatContains(substring, since = 0) {
|
|
148
|
+
const msgs = await this.chat(since);
|
|
149
|
+
const found = msgs.some(m => m.message.includes(substring));
|
|
150
|
+
if (!found) {
|
|
151
|
+
const recent = msgs.map(m => m.message).slice(-5).join(', ');
|
|
152
|
+
throw new Error(`assertChatContains: "${substring}" not found in chat. Recent: [${recent}]`);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Wait until a scoreboard value equals expected, up to timeout ms.
|
|
157
|
+
*/
|
|
158
|
+
async waitForScore(player, obj, expected, timeoutMs = 5000, pollMs = 100) {
|
|
159
|
+
const start = Date.now();
|
|
160
|
+
while (Date.now() - start < timeoutMs) {
|
|
161
|
+
try {
|
|
162
|
+
const val = await this.scoreboard(player, obj);
|
|
163
|
+
if (val === expected)
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
catch { /* ignore transient errors */ }
|
|
167
|
+
await new Promise(r => setTimeout(r, pollMs));
|
|
168
|
+
}
|
|
169
|
+
const final = await this.scoreboard(player, obj);
|
|
170
|
+
throw new Error(`waitForScore: ${player}/${obj} never reached ${expected} (last: ${final})`);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
exports.MCTestClient = MCTestClient;
|
|
174
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RedScript MC Integration Test Runner
|
|
3
|
+
*
|
|
4
|
+
* Compiles a .mcrs file, installs it to a running Paper server,
|
|
5
|
+
* runs test scenarios, and reports results.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* npx ts-node src/mc-test/runner.ts src/examples/counter.mcrs
|
|
9
|
+
*
|
|
10
|
+
* Requires:
|
|
11
|
+
* - Paper server running with TestHarnessPlugin
|
|
12
|
+
* - MC_SERVER_DIR env var pointing to server directory
|
|
13
|
+
* - MC_HOST and MC_PORT env vars (default: localhost:25561)
|
|
14
|
+
*/
|
|
15
|
+
import { MCTestClient } from './client';
|
|
16
|
+
export interface TestCase {
|
|
17
|
+
name: string;
|
|
18
|
+
run: (mc: MCTestClient) => Promise<void>;
|
|
19
|
+
}
|
|
20
|
+
export interface TestResult {
|
|
21
|
+
name: string;
|
|
22
|
+
passed: boolean;
|
|
23
|
+
error?: string;
|
|
24
|
+
durationMs: number;
|
|
25
|
+
}
|
|
26
|
+
export declare function runMCTests(sourceFile: string, tests: TestCase[], options?: {
|
|
27
|
+
skipInstall?: boolean;
|
|
28
|
+
}): Promise<TestResult[]>;
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* RedScript MC Integration Test Runner
|
|
4
|
+
*
|
|
5
|
+
* Compiles a .mcrs file, installs it to a running Paper server,
|
|
6
|
+
* runs test scenarios, and reports results.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* npx ts-node src/mc-test/runner.ts src/examples/counter.mcrs
|
|
10
|
+
*
|
|
11
|
+
* Requires:
|
|
12
|
+
* - Paper server running with TestHarnessPlugin
|
|
13
|
+
* - MC_SERVER_DIR env var pointing to server directory
|
|
14
|
+
* - MC_HOST and MC_PORT env vars (default: localhost:25561)
|
|
15
|
+
*/
|
|
16
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
17
|
+
if (k2 === undefined) k2 = k;
|
|
18
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
19
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
20
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
21
|
+
}
|
|
22
|
+
Object.defineProperty(o, k2, desc);
|
|
23
|
+
}) : (function(o, m, k, k2) {
|
|
24
|
+
if (k2 === undefined) k2 = k;
|
|
25
|
+
o[k2] = m[k];
|
|
26
|
+
}));
|
|
27
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
28
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
29
|
+
}) : function(o, v) {
|
|
30
|
+
o["default"] = v;
|
|
31
|
+
});
|
|
32
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
33
|
+
var ownKeys = function(o) {
|
|
34
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
35
|
+
var ar = [];
|
|
36
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
37
|
+
return ar;
|
|
38
|
+
};
|
|
39
|
+
return ownKeys(o);
|
|
40
|
+
};
|
|
41
|
+
return function (mod) {
|
|
42
|
+
if (mod && mod.__esModule) return mod;
|
|
43
|
+
var result = {};
|
|
44
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
45
|
+
__setModuleDefault(result, mod);
|
|
46
|
+
return result;
|
|
47
|
+
};
|
|
48
|
+
})();
|
|
49
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
50
|
+
exports.runMCTests = runMCTests;
|
|
51
|
+
const fs = __importStar(require("fs"));
|
|
52
|
+
const path = __importStar(require("path"));
|
|
53
|
+
const client_1 = require("./client");
|
|
54
|
+
const compile_1 = require("../compile");
|
|
55
|
+
const MC_HOST = process.env.MC_HOST ?? 'localhost';
|
|
56
|
+
const MC_PORT = parseInt(process.env.MC_PORT ?? '25561');
|
|
57
|
+
const MC_SERVER_DIR = process.env.MC_SERVER_DIR ?? path.join(process.env.HOME, 'mc-test-server');
|
|
58
|
+
async function runMCTests(sourceFile, tests, options = {}) {
|
|
59
|
+
const mc = new client_1.MCTestClient(MC_HOST, MC_PORT);
|
|
60
|
+
// Check server is online
|
|
61
|
+
console.log(`Connecting to MC server at ${MC_HOST}:${MC_PORT}...`);
|
|
62
|
+
const online = await mc.isOnline();
|
|
63
|
+
if (!online) {
|
|
64
|
+
throw new Error(`MC server not reachable at ${MC_HOST}:${MC_PORT}. Start Paper server first.`);
|
|
65
|
+
}
|
|
66
|
+
console.log('✓ Server online');
|
|
67
|
+
if (!options.skipInstall) {
|
|
68
|
+
// Compile and install datapack
|
|
69
|
+
const outDir = path.join(MC_SERVER_DIR, 'world', 'datapacks', 'redscript-test');
|
|
70
|
+
console.log(`Compiling ${sourceFile}...`);
|
|
71
|
+
const ns = path.basename(sourceFile, '.mcrs');
|
|
72
|
+
const result = (0, compile_1.compile)(fs.readFileSync(sourceFile, 'utf-8'), { namespace: ns, filePath: sourceFile });
|
|
73
|
+
if (!result.files) {
|
|
74
|
+
throw new Error('Compilation failed');
|
|
75
|
+
}
|
|
76
|
+
// Write files
|
|
77
|
+
fs.mkdirSync(outDir, { recursive: true });
|
|
78
|
+
for (const file of result.files) {
|
|
79
|
+
const filePath = path.join(outDir, file.path);
|
|
80
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
81
|
+
fs.writeFileSync(filePath, file.content);
|
|
82
|
+
}
|
|
83
|
+
console.log(`✓ Datapack installed to ${outDir}`);
|
|
84
|
+
// Reload datapacks
|
|
85
|
+
await mc.command('/reload');
|
|
86
|
+
await mc.ticks(40); // wait 2s for reload
|
|
87
|
+
console.log('✓ Datapacks reloaded');
|
|
88
|
+
}
|
|
89
|
+
// Run tests
|
|
90
|
+
const results = [];
|
|
91
|
+
for (const test of tests) {
|
|
92
|
+
await mc.reset(); // clear logs before each test
|
|
93
|
+
const start = Date.now();
|
|
94
|
+
try {
|
|
95
|
+
await test.run(mc);
|
|
96
|
+
results.push({ name: test.name, passed: true, durationMs: Date.now() - start });
|
|
97
|
+
console.log(` ✓ ${test.name} (${Date.now() - start}ms)`);
|
|
98
|
+
}
|
|
99
|
+
catch (err) {
|
|
100
|
+
results.push({
|
|
101
|
+
name: test.name,
|
|
102
|
+
passed: false,
|
|
103
|
+
error: err.message,
|
|
104
|
+
durationMs: Date.now() - start
|
|
105
|
+
});
|
|
106
|
+
console.log(` ✗ ${test.name}: ${err.message}`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
// Summary
|
|
110
|
+
const passed = results.filter(r => r.passed).length;
|
|
111
|
+
const failed = results.length - passed;
|
|
112
|
+
console.log(`\nResults: ${passed}/${results.length} passed${failed > 0 ? ` (${failed} FAILED)` : ''}`);
|
|
113
|
+
return results;
|
|
114
|
+
}
|
|
115
|
+
// CLI entry point
|
|
116
|
+
if (require.main === module) {
|
|
117
|
+
const sourceFile = process.argv[2];
|
|
118
|
+
if (!sourceFile) {
|
|
119
|
+
console.error('Usage: ts-node runner.ts <source.mcrs>');
|
|
120
|
+
process.exit(1);
|
|
121
|
+
}
|
|
122
|
+
// Example test suite (replace with actual tests)
|
|
123
|
+
const exampleTests = [
|
|
124
|
+
{
|
|
125
|
+
name: 'server is online',
|
|
126
|
+
run: async (mc) => {
|
|
127
|
+
const status = await mc.status();
|
|
128
|
+
if (!status.online)
|
|
129
|
+
throw new Error('Server not online');
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
name: 'datapack loads without errors',
|
|
134
|
+
run: async (mc) => {
|
|
135
|
+
await mc.command('/reload');
|
|
136
|
+
await mc.ticks(20);
|
|
137
|
+
// If reload didn't crash, we're good
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
];
|
|
141
|
+
runMCTests(sourceFile, exampleTests)
|
|
142
|
+
.then(results => {
|
|
143
|
+
const failed = results.filter(r => !r.passed);
|
|
144
|
+
process.exit(failed.length > 0 ? 1 : 0);
|
|
145
|
+
})
|
|
146
|
+
.catch(err => {
|
|
147
|
+
console.error(err.message);
|
|
148
|
+
process.exit(1);
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
//# sourceMappingURL=runner.js.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MC Test Setup Script
|
|
3
|
+
*
|
|
4
|
+
* Pre-compiles all RedScript test fixtures into the datapack directory.
|
|
5
|
+
* Run this ONCE before starting the Paper server, or before running tests
|
|
6
|
+
* with a fresh server.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* MC_SERVER_DIR=~/mc-test-server npx ts-node src/mc-test/setup.ts
|
|
10
|
+
*/
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* MC Test Setup Script
|
|
4
|
+
*
|
|
5
|
+
* Pre-compiles all RedScript test fixtures into the datapack directory.
|
|
6
|
+
* Run this ONCE before starting the Paper server, or before running tests
|
|
7
|
+
* with a fresh server.
|
|
8
|
+
*
|
|
9
|
+
* Usage:
|
|
10
|
+
* MC_SERVER_DIR=~/mc-test-server npx ts-node src/mc-test/setup.ts
|
|
11
|
+
*/
|
|
12
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
15
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
16
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
17
|
+
}
|
|
18
|
+
Object.defineProperty(o, k2, desc);
|
|
19
|
+
}) : (function(o, m, k, k2) {
|
|
20
|
+
if (k2 === undefined) k2 = k;
|
|
21
|
+
o[k2] = m[k];
|
|
22
|
+
}));
|
|
23
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
24
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
25
|
+
}) : function(o, v) {
|
|
26
|
+
o["default"] = v;
|
|
27
|
+
});
|
|
28
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
29
|
+
var ownKeys = function(o) {
|
|
30
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
31
|
+
var ar = [];
|
|
32
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
33
|
+
return ar;
|
|
34
|
+
};
|
|
35
|
+
return ownKeys(o);
|
|
36
|
+
};
|
|
37
|
+
return function (mod) {
|
|
38
|
+
if (mod && mod.__esModule) return mod;
|
|
39
|
+
var result = {};
|
|
40
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
41
|
+
__setModuleDefault(result, mod);
|
|
42
|
+
return result;
|
|
43
|
+
};
|
|
44
|
+
})();
|
|
45
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
46
|
+
const fs = __importStar(require("fs"));
|
|
47
|
+
const path = __importStar(require("path"));
|
|
48
|
+
const compile_1 = require("../compile");
|
|
49
|
+
const MC_SERVER_DIR = process.env.MC_SERVER_DIR ?? path.join(process.env.HOME, 'mc-test-server');
|
|
50
|
+
const DATAPACK_DIR = path.join(MC_SERVER_DIR, 'world', 'datapacks', 'redscript-test');
|
|
51
|
+
const EXAMPLES_DIR = path.join(__dirname, '../examples');
|
|
52
|
+
function writeFixture(source, namespace) {
|
|
53
|
+
const result = (0, compile_1.compile)(source, { namespace });
|
|
54
|
+
let fileCount = 0;
|
|
55
|
+
for (const file of result.files ?? []) {
|
|
56
|
+
const filePath = path.join(DATAPACK_DIR, file.path);
|
|
57
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
58
|
+
fs.writeFileSync(filePath, file.content);
|
|
59
|
+
fileCount++;
|
|
60
|
+
}
|
|
61
|
+
console.log(` ✓ ${namespace} (${fileCount} files)`);
|
|
62
|
+
}
|
|
63
|
+
function main() {
|
|
64
|
+
console.log(`Setting up MC test fixtures in:\n ${DATAPACK_DIR}\n`);
|
|
65
|
+
fs.mkdirSync(DATAPACK_DIR, { recursive: true });
|
|
66
|
+
// Example files
|
|
67
|
+
const exampleNamespaces = ['counter', 'world_manager'];
|
|
68
|
+
for (const ns of exampleNamespaces) {
|
|
69
|
+
const file = path.join(EXAMPLES_DIR, `${ns}.mcrs`);
|
|
70
|
+
if (fs.existsSync(file)) {
|
|
71
|
+
writeFixture(fs.readFileSync(file, 'utf-8'), ns);
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
console.log(` ⚠ ${ns}.mcrs not found, skipping`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
// Inline test fixtures
|
|
78
|
+
writeFixture(`
|
|
79
|
+
@tick
|
|
80
|
+
fn on_tick() {
|
|
81
|
+
scoreboard_set("#tick_counter", "ticks", scoreboard_get("#tick_counter", "ticks") + 1)
|
|
82
|
+
}
|
|
83
|
+
`, 'tick_test');
|
|
84
|
+
writeFixture(`
|
|
85
|
+
fn check_score() {
|
|
86
|
+
let x: int = scoreboard_get("#check_x", "test_score")
|
|
87
|
+
if (x > 5) {
|
|
88
|
+
scoreboard_set("#check_x", "result", 1)
|
|
89
|
+
} else {
|
|
90
|
+
scoreboard_set("#check_x", "result", 0)
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
`, 'inline_test');
|
|
94
|
+
console.log('\n✅ All fixtures written. Restart the MC server to load them.');
|
|
95
|
+
console.log(' Then run: MC_SERVER_DIR=... npx jest mc-integration --testTimeout=60000');
|
|
96
|
+
}
|
|
97
|
+
main();
|
|
98
|
+
//# sourceMappingURL=setup.js.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface ValidationResult {
|
|
2
|
+
valid: boolean;
|
|
3
|
+
error?: string;
|
|
4
|
+
}
|
|
5
|
+
export declare class MCCommandValidator {
|
|
6
|
+
private readonly root;
|
|
7
|
+
private readonly rootChildren;
|
|
8
|
+
constructor(commandsPath: string);
|
|
9
|
+
validate(line: string): ValidationResult;
|
|
10
|
+
private hasRootCommand;
|
|
11
|
+
private validateExecute;
|
|
12
|
+
private validateScoreboard;
|
|
13
|
+
private validateFunction;
|
|
14
|
+
private validateData;
|
|
15
|
+
private validateReturn;
|
|
16
|
+
private validateAgainstTree;
|
|
17
|
+
}
|