diff options
Diffstat (limited to 'tests/extended.zig')
| -rw-r--r-- | tests/extended.zig | 306 |
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 @@ | |||
| 1 | const std = @import("std"); | ||
| 2 | const clap = @import("../index.zig"); | ||
| 3 | |||
| 4 | const debug = std.debug; | ||
| 5 | const mem = std.mem; | ||
| 6 | const core = clap.core; | ||
| 7 | const extended = clap.extended; | ||
| 8 | |||
| 9 | const assert = debug.assert; | ||
| 10 | |||
| 11 | const ArgSliceIterator = core.ArgSliceIterator; | ||
| 12 | const Names = core.Names; | ||
| 13 | const Clap = extended.Clap; | ||
| 14 | const Param = extended.Param; | ||
| 15 | const Parser = extended.Parser; | ||
| 16 | |||
| 17 | pub 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 | |||
| 66 | test "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 | |||
| 162 | test "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 | |||
| 234 | test "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 | ||