const std = @import("std"); const ArgumentType = @import("ArgumentType"); const ParsedValue = ArgumentType.ParsedValue; test "ParsedValue: parse boolean true variants" { const test_cases = [_][]const u8{ "true", "TRUE", "True", "1", "yes", "YES", "on", "ON" }; for (test_cases) |str| { const parsed = try ParsedValue.fromString(.bool, str, std.testing.allocator); try std.testing.expectEqual(true, parsed.bool); } } test "ParsedValue: parse boolean false variants" { const test_cases = [_][]const u8{ "false", "FALSE", "False", "0", "no", "NO", "off", "OFF" }; for (test_cases) |str| { const parsed = try ParsedValue.fromString(.bool, str, std.testing.allocator); try std.testing.expectEqual(false, parsed.bool); } } test "ParsedValue: parse boolean invalid" { const result = ParsedValue.fromString(.bool, "maybe", std.testing.allocator); try std.testing.expectError(error.InvalidValue, result); } test "ParsedValue: parse unsigned integers" { const parsed_u8 = try ParsedValue.fromString(.u8, "255", std.testing.allocator); try std.testing.expectEqual(@as(u8, 255), parsed_u8.u8); const parsed_u16 = try ParsedValue.fromString(.u16, "65535", std.testing.allocator); try std.testing.expectEqual(@as(u16, 65535), parsed_u16.u16); const parsed_u32 = try ParsedValue.fromString(.u32, "4294967295", std.testing.allocator); try std.testing.expectEqual(@as(u32, 4294967295), parsed_u32.u32); const parsed_u64 = try ParsedValue.fromString(.u64, "18446744073709551615", std.testing.allocator); try std.testing.expectEqual(@as(u64, 18446744073709551615), parsed_u64.u64); } test "ParsedValue: parse signed integers" { const parsed_i8 = try ParsedValue.fromString(.i8, "-128", std.testing.allocator); try std.testing.expectEqual(@as(i8, -128), parsed_i8.i8); const parsed_i16 = try ParsedValue.fromString(.i16, "-32768", std.testing.allocator); try std.testing.expectEqual(@as(i16, -32768), parsed_i16.i16); const parsed_i32 = try ParsedValue.fromString(.i32, "-2147483648", std.testing.allocator); try std.testing.expectEqual(@as(i32, -2147483648), parsed_i32.i32); const parsed_i64 = try ParsedValue.fromString(.i64, "9223372036854775807", std.testing.allocator); try std.testing.expectEqual(@as(i64, 9223372036854775807), parsed_i64.i64); } test "ParsedValue: parse integers with hex prefix" { const parsed = try ParsedValue.fromString(.u32, "0xFF", std.testing.allocator); try std.testing.expectEqual(@as(u32, 255), parsed.u32); } test "ParsedValue: parse integers with binary prefix" { const parsed = try ParsedValue.fromString(.u8, "0b11111111", std.testing.allocator); try std.testing.expectEqual(@as(u8, 255), parsed.u8); } test "ParsedValue: parse integer overflow" { const result = ParsedValue.fromString(.u8, "256", std.testing.allocator); try std.testing.expectError(error.Overflow, result); } test "ParsedValue: parse integer invalid" { const result = ParsedValue.fromString(.i32, "not a number", std.testing.allocator); try std.testing.expectError(error.InvalidCharacter, result); } test "ParsedValue: parse string" { const parsed = try ParsedValue.fromString(.string, "hello world", std.testing.allocator); defer std.testing.allocator.free(parsed.string); try std.testing.expectEqualStrings("hello world", parsed.string); } test "ParsedValue: parse empty string" { const parsed = try ParsedValue.fromString(.string, "", std.testing.allocator); defer std.testing.allocator.free(parsed.string); try std.testing.expectEqualStrings("", parsed.string); } test "ParsedValue: parse enum" { const Color = enum { red, green, blue }; const parsed = try ParsedValue.parseEnum(Color, "green", std.testing.allocator); defer std.testing.allocator.free(parsed.enum_type.name); try std.testing.expectEqualStrings("green", parsed.enum_type.name); try std.testing.expectEqual(@as(usize, 1), parsed.enum_type.value); } test "ParsedValue: parse enum invalid" { const Color = enum { red, green, blue }; const result = ParsedValue.parseEnum(Color, "yellow", std.testing.allocator); try std.testing.expectError(error.InvalidValue, result); } test "ParsedValue: toTypedValue bool" { const parsed = ParsedValue{ .bool = true }; const value = parsed.toTypedValue(bool); try std.testing.expectEqual(true, value); } test "ParsedValue: toTypedValue optional bool" { const parsed = ParsedValue{ .bool = false }; const value = parsed.toTypedValue(?bool); try std.testing.expectEqual(@as(?bool, false), value); } test "ParsedValue: toTypedValue integers" { { const parsed = ParsedValue{ .u32 = 42 }; const value = parsed.toTypedValue(u32); try std.testing.expectEqual(@as(u32, 42), value); } { const parsed = ParsedValue{ .i64 = -999 }; const value = parsed.toTypedValue(i64); try std.testing.expectEqual(@as(i64, -999), value); } } test "ParsedValue: toTypedValue string" { const parsed = ParsedValue{ .string = "test" }; const value = parsed.toTypedValue([]const u8); try std.testing.expectEqualStrings("test", value); } test "ParsedValue: toTypedValue enum" { const Color = enum { red, green, blue }; const parsed = ParsedValue{ .enum_type = .{ .name = "blue", .value = 2, }, }; const value = parsed.toTypedValue(Color); try std.testing.expectEqual(Color.blue, value); } test "ParsedValue: round-trip bool" { const parsed = try ParsedValue.fromString(.bool, "true", std.testing.allocator); const value = parsed.toTypedValue(bool); try std.testing.expectEqual(true, value); } test "ParsedValue: round-trip integer" { const parsed = try ParsedValue.fromString(.u32, "12345", std.testing.allocator); const value = parsed.toTypedValue(u32); try std.testing.expectEqual(@as(u32, 12345), value); } test "ParsedValue: round-trip string" { const parsed = try ParsedValue.fromString(.string, "hello", std.testing.allocator); defer std.testing.allocator.free(parsed.string); const value = parsed.toTypedValue([]const u8); try std.testing.expectEqualStrings("hello", value); } test "ParsedValue: round-trip enum" { const LogLevel = enum { debug, info, warn, @"error" }; const parsed = try ParsedValue.parseEnum(LogLevel, "warn", std.testing.allocator); defer std.testing.allocator.free(parsed.enum_type.name); const value = parsed.toTypedValue(LogLevel); try std.testing.expectEqual(LogLevel.warn, value); }