Skip to content

Commit

Permalink
Test failures
Browse files Browse the repository at this point in the history
Closes #32
  • Loading branch information
sam701 committed Dec 31, 2023
1 parent a9c3201 commit d8e0508
Show file tree
Hide file tree
Showing 4 changed files with 142 additions and 9 deletions.
2 changes: 1 addition & 1 deletion src/command.zig
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,6 @@ pub const PositionalArgs = struct {

pub const PositionalArg = struct {
name: []const u8,
help: []const u8,
help: ?[]const u8 = null,
value_ref: *ValueRef,
};
6 changes: 4 additions & 2 deletions src/help.zig
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,10 @@ const HelpPrinter = struct {
while (it.next()) |parg| {
self.printer.write(" ");
self.printer.printInColor(self.help_config.color_option, parg.name);
self.printer.printSpaces(max_arg_width - parg.name.len + 3);
self.printer.write(parg.help);
if (parg.help) |help| {
self.printer.printSpaces(max_arg_width - parg.name.len + 3);
self.printer.write(help);
}
self.printer.printNewLine();
}
}
Expand Down
3 changes: 3 additions & 0 deletions src/parser.zig
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,9 @@ pub fn Parser(comptime Iterator: type) type {
if (posArgRef.value_type == vref.ValueType.single) {
self.position_argument_ix += 1;
}
} else {
self.error_data = ErrorData{ .entity_name = cmd.name };
return error.CommandDoesNotHavePositionalArguments;
}
},
}
Expand Down
140 changes: 134 additions & 6 deletions src/tests.zig
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const AppRunner = @import("app_runner.zig").AppRunner;

const expect = std.testing.expect;
const alloc = std.testing.allocator;
const expectError = std.testing.expectError;

const StringSliceIterator = struct {
items: []const []const u8,
Expand All @@ -30,13 +31,13 @@ fn runner() *AppRunner {
}

fn run(app: *const command.App, items: []const []const u8) !void {
const it = StringSliceIterator{
.items = items,
};

var parser = try Parser(StringSliceIterator).init(app, it, alloc);
var parser = try Parser(StringSliceIterator).init(
app,
StringSliceIterator{ .items = items },
alloc,
);
defer parser.deinit();
_ = try parser.parse();
parser.deinit();
}

fn dummy_action() !void {}
Expand Down Expand Up @@ -305,3 +306,130 @@ test "parse enums" {

alloc.free(aa);
}

test "unknown option" {
var r = runner();
defer r.deinit();
var aa: []const u8 = undefined;
const opt = command.Option{
.long_name = "aa",
.short_alias = 'a',
.help = "option aa",
.value_ref = r.mkRef(&aa),
};

try expectError(error.UnknownOption, runOptions(&.{ "abc", "--bad", "val" }, &.{opt}));

try expectError(error.UnknownOptionAlias, runOptions(&.{ "abc", "-b", "val" }, &.{opt}));
}

test "unknown subcommand" {
var r = runner();
defer r.deinit();

const app = command.App{
.command = command.Command{
.name = "abc",
.target = command.CommandTarget{
.subcommands = &.{},
},
},
};

try expectError(error.UnknownSubcommand, run(&app, &.{ "abc", "bad" }));
}

test "missing subcommand" {
var r = runner();
defer r.deinit();

const app = command.App{
.command = command.Command{
.name = "abc",
.target = command.CommandTarget{
.subcommands = &.{},
},
},
};

try expectError(error.MissingSubcommand, run(&app, &.{"abc"}));
try expectError(error.CommandDoesNotHavePositionalArguments, run(&app, &.{ "abc", "--", "3" }));
}

test "missing required option" {
var r = runner();
defer r.deinit();
var aa: []const u8 = undefined;
const opt = command.Option{
.long_name = "aa",
.short_alias = 'a',
.required = true,
.help = "option aa",
.value_ref = r.mkRef(&aa),
};

try expectError(error.MissingRequiredOption, runOptions(&.{"abc"}, &.{opt}));
try expectError(error.MissingOptionValue, runOptions(&.{ "abc", "--aa" }, &.{opt}));
}

test "missing positional argument" {
var r = runner();
defer r.deinit();

var x: usize = 0;

const app = command.App{
.command = command.Command{
.name = "abc",
.target = command.CommandTarget{
.action = command.CommandAction{
.positional_args = command.PositionalArgs{
.required = &.{
command.PositionalArg{
.name = "PA1",
.value_ref = r.mkRef(&x),
},
},
},
.exec = dummy_action,
},
},
},
};

try expectError(error.MissingRequiredPositionalArgument, run(&app, &.{"abc"}));
try expectError(error.UnexpectedPositionalArgument, run(&app, &.{ "abc", "3", "4" }));
}

test "command without positional arguments" {
var r = runner();
defer r.deinit();

const app = command.App{
.command = command.Command{
.name = "abc",
.target = command.CommandTarget{
.action = command.CommandAction{
.exec = dummy_action,
},
},
},
};

try expectError(error.CommandDoesNotHavePositionalArguments, run(&app, &.{ "abc", "3", "abc" }));
}

test "invalid value" {
var r = runner();
defer r.deinit();
var aa: usize = undefined;
const opt = command.Option{
.long_name = "aa",
.short_alias = 'a',
.required = true,
.help = "option aa",
.value_ref = r.mkRef(&aa),
};

try expectError(error.InvalidValue, runOptions(&.{ "abc", "--aa", "bad" }, &.{opt}));
}

0 comments on commit d8e0508

Please sign in to comment.