nice-data/tests/reify.zig
2023-12-01 22:35:18 -08:00

145 lines
4.6 KiB
Zig

const std = @import("std");
const nice = @import("nice");
fn reifyScalar(comptime scalar: []const u8, expected: anytype) !void {
try reifyScalarWithOptions(scalar, expected, .{});
}
fn reifyScalarWithOptions(comptime scalar: []const u8, expected: anytype, options: nice.parser.Options) !void {
const allocator = std.testing.allocator;
var diagnostics = nice.Diagnostics{};
const parsed = try nice.parseBufferTo(
@TypeOf(expected),
allocator,
scalar ++ "\n",
&diagnostics,
options,
);
defer parsed.deinit();
try std.testing.expectEqual(expected, parsed.value);
}
test "reify integer" {
try reifyScalar("123", @as(u8, 123));
try reifyScalar("0123", @as(u8, 123));
try reifyScalar("1_23", @as(u8, 123));
try reifyScalar("-01_23", @as(i8, -123));
}
test "reify hexadecimal" {
try reifyScalar("0x123", @as(i64, 0x123));
try reifyScalar("0x0123", @as(i64, 0x123));
try reifyScalar("0x01_23", @as(i64, 0x123));
try reifyScalar("-0x01_23", @as(i64, -0x123));
}
test "reify octal" {
try reifyScalar("0o123", @as(i64, 0o123));
try reifyScalar("0o0123", @as(i64, 0o123));
try reifyScalar("0o01_23", @as(i64, 0o123));
try reifyScalar("-0o01_23", @as(i64, -0o123));
}
test "reify binary" {
try reifyScalar("0b1011", @as(i5, 0b1011));
try reifyScalar("0b01011", @as(i5, 0b1011));
try reifyScalar("0b010_11", @as(i5, 0b1011));
try reifyScalar("-0b010_11", @as(i5, -0b1011));
}
test "reify float" {
try reifyScalar("0.25", @as(f32, 0.25));
try reifyScalar("0.2_5", @as(f32, 0.25));
try reifyScalar("00.250", @as(f32, 0.25));
try reifyScalar("-0.25", @as(f32, -0.25));
}
test "reify hexfloat" {
try reifyScalar("0x0.25", @as(f64, 0x0.25));
try reifyScalar("0x0.2_5", @as(f64, 0x0.25));
try reifyScalar("0x0.250p1", @as(f64, 0x0.25p1));
try reifyScalar("-0x0.25", @as(f64, -0x0.25));
}
test "reify true" {
try reifyScalar("true", true);
try reifyScalar("True", true);
try reifyScalar("yes", true);
try reifyScalar("on", true);
}
test "reify false" {
try reifyScalar("false", false);
try reifyScalar("False", false);
try reifyScalar("no", false);
try reifyScalar("off", false);
}
test "reify custom true" {
const options = nice.parser.Options{ .truthy_boolean_scalars = &.{"correct"} };
try reifyScalarWithOptions("correct", true, options);
}
test "reify true case insensitive" {
try std.testing.expectError(error.BadValue, reifyScalar("TRUE", true));
const options = nice.parser.Options{ .case_insensitive_scalar_coersion = true };
try reifyScalarWithOptions("TRUE", true, options);
}
test "reify custom false" {
const options = nice.parser.Options{ .falsy_boolean_scalars = &.{"incorrect"} };
try reifyScalarWithOptions("incorrect", false, options);
}
test "reify false case insensitive" {
try std.testing.expectError(error.BadValue, reifyScalar("FALSE", false));
const options = nice.parser.Options{ .case_insensitive_scalar_coersion = true };
try reifyScalarWithOptions("FALSE", false, options);
}
test "reify null" {
try reifyScalar("null", @as(?u8, null));
try reifyScalar("nil", @as(?u8, null));
try reifyScalar("None", @as(?u8, null));
}
test "reify custom null" {
const options = nice.parser.Options{ .null_scalars = &.{"nothing"} };
try reifyScalarWithOptions("nothing", @as(?u8, null), options);
}
test "reify null case insensitive" {
// this is a little weird because when the null string mismatches, it will try to
// parse the child optional type and produce either a value or an error from that,
// so the error received depends on whether or not the optional child type fails to
// parse the given value.
try std.testing.expectError(error.InvalidCharacter, reifyScalar("NULL", @as(?u8, null)));
const options = nice.parser.Options{ .case_insensitive_scalar_coersion = true };
try reifyScalarWithOptions("NULL", @as(?u8, null), options);
}
test "reify void" {
// A void scalar cannot exist on its own as it is not distinguishable from an empty
// document.
const Void = struct { void: void };
try reifyScalar("void:", Void{ .void = void{} });
}
test "reify void scalar" {
const options = nice.parser.Options{ .default_object = .scalar };
try reifyScalarWithOptions("", void{}, options);
}
test "reify enum" {
const Enum = enum { one, two };
try reifyScalar(".one", Enum.one);
}
test "reify enum no dot" {
const options = nice.parser.Options{ .expect_enum_dot = false };
const Enum = enum { one, two };
try reifyScalarWithOptions("two", Enum.two, options);
}