@tkeron/commands 0.3.0 → 0.4.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.
@@ -0,0 +1,187 @@
1
+ import { describe, expect, it, mock, spyOn } from "bun:test";
2
+ import { getCommands } from "../src/index.js";
3
+
4
+ describe("Backward Compatibility - Legacy Syntax", () => {
5
+ it("should work exactly as before with key=value syntax", () => {
6
+ const logMock = spyOn(console, "log").mockImplementation(() => {});
7
+ const callback = mock();
8
+
9
+ const commands = getCommands("testapp", "1.0.0");
10
+ commands
11
+ .addCommand("build")
12
+ .addOption("output", "./dist")
13
+ .addOption("format", "json")
14
+ .addPositionedArgument("source")
15
+ .setCallback(callback);
16
+
17
+ commands.start([
18
+ "node",
19
+ "app",
20
+ "build",
21
+ "src",
22
+ "output=build",
23
+ "format=xml",
24
+ ]);
25
+
26
+ expect(callback).toBeCalledTimes(1);
27
+ const options = callback.mock.calls[0][0];
28
+ expect(options.source).toBe("src");
29
+ expect(options.output).toBe("build");
30
+ expect(options.format).toBe("xml");
31
+
32
+ logMock.mockRestore();
33
+ });
34
+
35
+ it("should maintain help command functionality", () => {
36
+ const logs: any[] = [];
37
+ const logMock = spyOn(console, "log").mockImplementation((...args: any) => {
38
+ logs.push(args);
39
+ });
40
+
41
+ const commands = getCommands("testapp", "1.0.0");
42
+ commands.addCommand("build").addDescription("Build the project");
43
+
44
+ commands.start(["node", "app", "help"]);
45
+
46
+ expect(logs.length).toBeGreaterThan(0);
47
+ logMock.mockRestore();
48
+ });
49
+
50
+ it("should maintain version command functionality", () => {
51
+ const logs: any[] = [];
52
+ const logMock = spyOn(console, "log").mockImplementation((...args: any) => {
53
+ logs.push(args);
54
+ });
55
+
56
+ const commands = getCommands("testapp", "1.2.3");
57
+ commands.start(["node", "app", "version"]);
58
+
59
+ expect(logs.length).toBeGreaterThan(0);
60
+ expect(logs[0][0]).toContain("1.2.3");
61
+ logMock.mockRestore();
62
+ });
63
+ });
64
+
65
+ describe("Standard CLI Syntax - New Features", () => {
66
+ it("should support boolean flags with new API", () => {
67
+ const logMock = spyOn(console, "log").mockImplementation(() => {});
68
+ const callback = mock();
69
+
70
+ const commands = getCommands("testapp", "1.0.0");
71
+ commands
72
+ .addCommand("build")
73
+ .addFlag("verbose", "v", "Enable verbose output")
74
+ .addFlag("watch", "w", "Watch mode")
75
+ .setCallback(callback);
76
+
77
+ commands.start(["node", "app", "build", "--verbose", "--watch"]);
78
+
79
+ expect(callback).toBeCalledTimes(1);
80
+ const options = callback.mock.calls[0][0];
81
+ expect(options.verbose).toBe(true);
82
+ expect(options.watch).toBe(true);
83
+
84
+ logMock.mockRestore();
85
+ });
86
+
87
+ it("should support string options with short flags", () => {
88
+ const logMock = spyOn(console, "log").mockImplementation(() => {});
89
+ const callback = mock();
90
+
91
+ const commands = getCommands("testapp", "1.0.0");
92
+ commands
93
+ .addCommand("serve")
94
+ .addStringOption("port", "p", "Port number", { default: "3000" })
95
+ .addStringOption("host", "h", "Host", { default: "localhost" })
96
+ .setCallback(callback);
97
+
98
+ commands.start(["node", "app", "serve", "-p", "8080"]);
99
+
100
+ expect(callback).toBeCalledTimes(1);
101
+ const options = callback.mock.calls[0][0];
102
+ expect(options.port).toBe("8080");
103
+ expect(options.host).toBe("localhost");
104
+
105
+ logMock.mockRestore();
106
+ });
107
+
108
+ it("should support number options", () => {
109
+ const logMock = spyOn(console, "log").mockImplementation(() => {});
110
+ const callback = mock();
111
+
112
+ const commands = getCommands("testapp", "1.0.0");
113
+ commands
114
+ .addCommand("run")
115
+ .addNumberOption("count", "c", "Number of runs", { default: 1 })
116
+ .setCallback(callback);
117
+
118
+ commands.start(["node", "app", "run", "--count", "5"]);
119
+
120
+ expect(callback).toBeCalledTimes(1);
121
+ const options = callback.mock.calls[0][0];
122
+ expect(options.count).toBe(5);
123
+ expect(typeof options.count).toBe("number");
124
+
125
+ logMock.mockRestore();
126
+ });
127
+ });
128
+
129
+ describe("Mixed Syntax Support", () => {
130
+ it("should handle both legacy and standard syntax together", () => {
131
+ const logMock = spyOn(console, "log").mockImplementation(() => {});
132
+ const callback = mock();
133
+
134
+ const commands = getCommands("testapp", "1.0.0");
135
+ commands
136
+ .addCommand("deploy")
137
+ .addFlag("verbose", "v")
138
+ .addOption("env", "production")
139
+ .setCallback(callback);
140
+
141
+ commands.start(["node", "app", "deploy", "--verbose", "target=staging"]);
142
+
143
+ expect(callback).toBeCalledTimes(1);
144
+ const options = callback.mock.calls[0][0];
145
+ expect(options.verbose).toBe(true);
146
+ expect(options.target).toBe("staging");
147
+
148
+ logMock.mockRestore();
149
+ });
150
+ });
151
+
152
+ describe("Existing example.ts compatibility", () => {
153
+ it("should maintain exact behavior of examples/example.ts", () => {
154
+ const logMock = spyOn(console, "log").mockImplementation(() => {});
155
+ const callback = mock();
156
+
157
+ const commands = getCommands("test program", "0.0.14");
158
+ commands
159
+ .addCommand("com1")
160
+ .addAlias("c1")
161
+ .addOption("opt1")
162
+ .addOption("opt2")
163
+ .addDescription("command 001 test...")
164
+ .addPositionedArgument("pos0")
165
+ .addPositionedArgument("pos1")
166
+ .setCallback(callback);
167
+
168
+ commands.start([
169
+ "node",
170
+ "app",
171
+ "com1",
172
+ "pos0value",
173
+ "opt1=qw111erty",
174
+ "pos1value",
175
+ "opt2=as222d",
176
+ ]);
177
+
178
+ expect(callback).toBeCalledTimes(1);
179
+ const options = callback.mock.calls[0][0];
180
+ expect(options.pos0).toBe("pos0value");
181
+ expect(options.pos1).toBe("pos1value");
182
+ expect(options.opt1).toBe("qw111erty");
183
+ expect(options.opt2).toBe("as222d");
184
+
185
+ logMock.mockRestore();
186
+ });
187
+ });
@@ -0,0 +1,42 @@
1
+ import { afterEach, beforeEach, describe, expect, it, spyOn } from "bun:test";
2
+
3
+ describe("example e2e", () => {
4
+ let logs: any[] = [];
5
+ let spy: any;
6
+
7
+ beforeEach(() => {
8
+ logs = [];
9
+ spy = spyOn(globalThis.console, "log").mockImplementation((...args: any) => {
10
+ logs.push(args);
11
+ });
12
+ });
13
+
14
+ afterEach(() => {
15
+ spy.mockRestore();
16
+ });
17
+
18
+ it("should runs ok", (done) => {
19
+ expect(logs).toHaveLength(0);
20
+ import("../examples/example");
21
+ const check = () => {
22
+ const { commands } = globalThis;
23
+ if (!commands) return;
24
+ expect(logs).toHaveLength(8);
25
+ expect(logs[0]).toStrictEqual(["argument 'asdasd' not defined"]);
26
+ expect(logs[1]).toStrictEqual(["arguments 'pos0value, pos1value, asdasd' not defined"]);
27
+ expect(logs[2]).toStrictEqual([
28
+ {
29
+ opt1: "qw111erty",
30
+ opt2: "as222d",
31
+ pos0: "pos0value",
32
+ pos1: "pos1value",
33
+ pos3: "asdasd",
34
+ },
35
+ ]);
36
+ expect(logs).toHaveLength(8);
37
+ clearInterval(handler);
38
+ done();
39
+ };
40
+ const handler = setInterval(check, 10);
41
+ });
42
+ });