summaryrefslogtreecommitdiff
path: root/tests/extended.zig
diff options
context:
space:
mode:
Diffstat (limited to 'tests/extended.zig')
-rw-r--r--tests/extended.zig306
1 files changed, 0 insertions, 306 deletions
diff --git a/tests/extended.zig b/tests/extended.zig
deleted file mode 100644
index 9670814..0000000
--- a/tests/extended.zig
+++ /dev/null
@@ -1,306 +0,0 @@
1const std = @import("std");
2const clap = @import("../index.zig");
3
4const debug = std.debug;
5const mem = std.mem;
6const core = clap.core;
7const extended = clap.extended;
8
9const assert = debug.assert;
10
11const ArgSliceIterator = core.ArgSliceIterator;
12const Names = core.Names;
13const Clap = extended.Clap;
14const Param = extended.Param;
15const Parser = extended.Parser;
16
17pub fn Test(comptime Expect: type) type {
18 return struct {
19 const Self = this;
20
21 args: []const []const u8,
22 kind: Kind,
23
24 const Kind = union(enum) {
25 Success: Expect,
26 Fail: error,
27 };
28
29 pub fn success(args: []const []const u8, expected: Expect) Self {
30 return Self{
31 .args = args,
32 .kind = Kind{ .Success = expected },
33 };
34 }
35
36 pub fn fail(args: []const []const u8, err: error) Self {
37 return Self{
38 .args = args,
39 .kind = Kind{ .Fail = err },
40 };
41 }
42
43 pub fn run(t: Self, comptime parser: var) void {
44 var iter = ArgSliceIterator.init(t.args);
45 const actual = parser.parse(ArgSliceIterator.Error, &iter.iter);
46
47 switch (t.kind) {
48 Kind.Success => |expected| {
49 const actual_value = actual catch unreachable;
50 inline for (@typeInfo(Expect).Struct.fields) |field| {
51 assert(@field(expected, field.name) == @field(actual_value, field.name));
52 }
53 },
54 Kind.Fail => |expected| {
55 if (actual) |_| {
56 unreachable;
57 } else |actual_err| {
58 assert(actual_err == expected);
59 }
60 },
61 }
62 }
63 };
64}
65
66test "clap.extended: short" {
67 const S = struct {
68 a: bool,
69 b: u8,
70 };
71
72 const parser = comptime Clap(S){
73 .default = S{
74 .a = false,
75 .b = 0,
76 },
77 .params = []Param{
78 p: {
79 var res = Param.flag("a", Names.short('a'));
80 res.required = true;
81 res.position = 0;
82 break :p res;
83 },
84 Param.option("b", Names.short('b'), Parser.int(u8, 10)),
85 },
86 };
87
88 const T = Test(S);
89 const tests = []T{
90 T.success(
91 [][]const u8{"-a"},
92 S{
93 .a = true,
94 .b = 0,
95 },
96 ),
97 T.success(
98 [][]const u8{ "-a", "-b", "100" },
99 S{
100 .a = true,
101 .b = 100,
102 },
103 ),
104 T.success(
105 [][]const u8{ "-a", "-b=100" },
106 S{
107 .a = true,
108 .b = 100,
109 },
110 ),
111 T.success(
112 [][]const u8{ "-a", "-b100" },
113 S{
114 .a = true,
115 .b = 100,
116 },
117 ),
118 T.success(
119 [][]const u8{ "-ab", "100" },
120 S{
121 .a = true,
122 .b = 100,
123 },
124 ),
125 T.success(
126 [][]const u8{"-ab=100"},
127 S{
128 .a = true,
129 .b = 100,
130 },
131 ),
132 T.success(
133 [][]const u8{"-ab100"},
134 S{
135 .a = true,
136 .b = 100,
137 },
138 ),
139 T.fail(
140 [][]const u8{"-q"},
141 error.InvalidArgument,
142 ),
143 T.fail(
144 [][]const u8{"--a"},
145 error.InvalidArgument,
146 ),
147 T.fail(
148 [][]const u8{"-b=100"},
149 error.ParamNotHandled,
150 ),
151 T.fail(
152 [][]const u8{ "-b=100", "-a" },
153 error.InvalidArgument,
154 ),
155 };
156
157 for (tests) |t| {
158 t.run(parser);
159 }
160}
161
162test "clap.extended: long" {
163 const S = struct {
164 a: bool,
165 b: u8,
166 };
167
168 const parser = comptime Clap(S){
169 .default = S{
170 .a = false,
171 .b = 0,
172 },
173 .params = []Param{
174 p: {
175 var res = Param.flag("a", Names.long("a"));
176 res.required = true;
177 res.position = 0;
178 break :p res;
179 },
180 Param.option("b", Names.long("b"), Parser.int(u8, 10)),
181 },
182 };
183
184 const T = Test(S);
185 const tests = []T{
186 T.success(
187 [][]const u8{"--a"},
188 S{
189 .a = true,
190 .b = 0,
191 },
192 ),
193 T.success(
194 [][]const u8{ "--a", "--b", "100" },
195 S{
196 .a = true,
197 .b = 100,
198 },
199 ),
200 T.success(
201 [][]const u8{ "--a", "--b=100" },
202 S{
203 .a = true,
204 .b = 100,
205 },
206 ),
207 T.fail(
208 [][]const u8{"--a=100"},
209 error.DoesntTakeValue,
210 ),
211 T.fail(
212 [][]const u8{"--q"},
213 error.InvalidArgument,
214 ),
215 T.fail(
216 [][]const u8{"-a"},
217 error.InvalidArgument,
218 ),
219 T.fail(
220 [][]const u8{"--b=100"},
221 error.ParamNotHandled,
222 ),
223 T.fail(
224 [][]const u8{ "--b=100", "--a" },
225 error.InvalidArgument,
226 ),
227 };
228
229 for (tests) |t| {
230 t.run(parser);
231 }
232}
233
234test "clap.extended: bare" {
235 const S = struct {
236 a: bool,
237 b: u8,
238 };
239
240 const parser = comptime Clap(S){
241 .default = S{
242 .a = false,
243 .b = 0,
244 },
245 .params = []Param{
246 p: {
247 var res = Param.flag("a", Names.bare("a"));
248 res.required = true;
249 res.position = 0;
250 break :p res;
251 },
252 Param.option("b", Names.bare("b"), Parser.int(u8, 10)),
253 },
254 };
255
256 const T = Test(S);
257 const tests = []T{
258 T.success(
259 [][]const u8{"a"},
260 S{
261 .a = true,
262 .b = 0,
263 },
264 ),
265 T.success(
266 [][]const u8{ "a", "b", "100" },
267 S{
268 .a = true,
269 .b = 100,
270 },
271 ),
272 T.success(
273 [][]const u8{ "a", "b=100" },
274 S{
275 .a = true,
276 .b = 100,
277 },
278 ),
279 T.fail(
280 [][]const u8{"a=100"},
281 error.DoesntTakeValue,
282 ),
283 T.fail(
284 [][]const u8{"--a"},
285 error.InvalidArgument,
286 ),
287 T.fail(
288 [][]const u8{"-a"},
289 error.InvalidArgument,
290 ),
291 T.fail(
292 [][]const u8{"b=100"},
293 error.ParamNotHandled,
294 ),
295 T.fail(
296 [][]const u8{ "b=100", "--a" },
297 error.InvalidArgument,
298 ),
299 };
300
301 for (tests) |t| {
302 t.run(parser);
303 }
304}
305
306// TODO: Test sub commands and sub field access