diff options
Diffstat (limited to 'src/link/tapi/yaml/test.zig')
| -rw-r--r-- | src/link/tapi/yaml/test.zig | 475 |
1 files changed, 475 insertions, 0 deletions
diff --git a/src/link/tapi/yaml/test.zig b/src/link/tapi/yaml/test.zig new file mode 100644 index 0000000000..8db9435885 --- /dev/null +++ b/src/link/tapi/yaml/test.zig @@ -0,0 +1,475 @@ +const std = @import("std"); +const mem = std.mem; +const testing = std.testing; + +const yaml_mod = @import("../yaml.zig"); +const Yaml = yaml_mod.Yaml; + +test "simple list" { + const source = + \\- a + \\- b + \\- c + ; + + var yaml = try Yaml.load(testing.allocator, source); + defer yaml.deinit(); + + try testing.expectEqual(yaml.docs.items.len, 1); + + const list = yaml.docs.items[0].list; + try testing.expectEqual(list.len, 3); + + try testing.expectEqualStrings("a", list[0].string); + try testing.expectEqualStrings("b", list[1].string); + try testing.expectEqualStrings("c", list[2].string); +} + +test "simple list typed as array of strings" { + const source = + \\- a + \\- b + \\- c + ; + + var yaml = try Yaml.load(testing.allocator, source); + defer yaml.deinit(); + + try testing.expectEqual(yaml.docs.items.len, 1); + + const arr = try yaml.parse([3][]const u8); + try testing.expectEqual(3, arr.len); + try testing.expectEqualStrings("a", arr[0]); + try testing.expectEqualStrings("b", arr[1]); + try testing.expectEqualStrings("c", arr[2]); +} + +test "simple list typed as array of ints" { + const source = + \\- 0 + \\- 1 + \\- 2 + ; + + var yaml = try Yaml.load(testing.allocator, source); + defer yaml.deinit(); + + try testing.expectEqual(yaml.docs.items.len, 1); + + const arr = try yaml.parse([3]u8); + try testing.expectEqualSlices(u8, &[_]u8{ 0, 1, 2 }, &arr); +} + +test "list of mixed sign integer" { + const source = + \\- 0 + \\- -1 + \\- 2 + ; + + var yaml = try Yaml.load(testing.allocator, source); + defer yaml.deinit(); + + try testing.expectEqual(yaml.docs.items.len, 1); + + const arr = try yaml.parse([3]i8); + try testing.expectEqualSlices(i8, &[_]i8{ 0, -1, 2 }, &arr); +} + +test "simple map untyped" { + const source = + \\a: 0 + ; + + var yaml = try Yaml.load(testing.allocator, source); + defer yaml.deinit(); + + try testing.expectEqual(yaml.docs.items.len, 1); + + const map = yaml.docs.items[0].map; + try testing.expect(map.contains("a")); + try testing.expectEqual(@as(i64, 0), map.get("a").?.int); +} + +test "simple map untyped with a list of maps" { + const source = + \\a: 0 + \\b: + \\ - foo: 1 + \\ bar: 2 + \\ - foo: 3 + \\ bar: 4 + \\c: 1 + ; + + var yaml = try Yaml.load(testing.allocator, source); + defer yaml.deinit(); + + try testing.expectEqual(yaml.docs.items.len, 1); + + const map = yaml.docs.items[0].map; + try testing.expect(map.contains("a")); + try testing.expect(map.contains("b")); + try testing.expect(map.contains("c")); + try testing.expectEqual(@as(i64, 0), map.get("a").?.int); + try testing.expectEqual(@as(i64, 1), map.get("c").?.int); + try testing.expectEqual(@as(i64, 1), map.get("b").?.list[0].map.get("foo").?.int); + try testing.expectEqual(@as(i64, 2), map.get("b").?.list[0].map.get("bar").?.int); + try testing.expectEqual(@as(i64, 3), map.get("b").?.list[1].map.get("foo").?.int); + try testing.expectEqual(@as(i64, 4), map.get("b").?.list[1].map.get("bar").?.int); +} + +test "simple map untyped with a list of maps. no indent" { + const source = + \\b: + \\- foo: 1 + \\c: 1 + ; + + var yaml = try Yaml.load(testing.allocator, source); + defer yaml.deinit(); + + try testing.expectEqual(yaml.docs.items.len, 1); + + const map = yaml.docs.items[0].map; + try testing.expect(map.contains("b")); + try testing.expect(map.contains("c")); + try testing.expectEqual(@as(i64, 1), map.get("c").?.int); + try testing.expectEqual(@as(i64, 1), map.get("b").?.list[0].map.get("foo").?.int); +} + +test "simple map untyped with a list of maps. no indent 2" { + const source = + \\a: 0 + \\b: + \\- foo: 1 + \\ bar: 2 + \\- foo: 3 + \\ bar: 4 + \\c: 1 + ; + + var yaml = try Yaml.load(testing.allocator, source); + defer yaml.deinit(); + + try testing.expectEqual(yaml.docs.items.len, 1); + + const map = yaml.docs.items[0].map; + try testing.expect(map.contains("a")); + try testing.expect(map.contains("b")); + try testing.expect(map.contains("c")); + try testing.expectEqual(@as(i64, 0), map.get("a").?.int); + try testing.expectEqual(@as(i64, 1), map.get("c").?.int); + try testing.expectEqual(@as(i64, 1), map.get("b").?.list[0].map.get("foo").?.int); + try testing.expectEqual(@as(i64, 2), map.get("b").?.list[0].map.get("bar").?.int); + try testing.expectEqual(@as(i64, 3), map.get("b").?.list[1].map.get("foo").?.int); + try testing.expectEqual(@as(i64, 4), map.get("b").?.list[1].map.get("bar").?.int); +} + +test "simple map typed" { + const source = + \\a: 0 + \\b: hello there + \\c: 'wait, what?' + ; + + var yaml = try Yaml.load(testing.allocator, source); + defer yaml.deinit(); + + const simple = try yaml.parse(struct { a: usize, b: []const u8, c: []const u8 }); + try testing.expectEqual(@as(usize, 0), simple.a); + try testing.expectEqualStrings("hello there", simple.b); + try testing.expectEqualStrings("wait, what?", simple.c); +} + +test "typed nested structs" { + const source = + \\a: + \\ b: hello there + \\ c: 'wait, what?' + ; + + var yaml = try Yaml.load(testing.allocator, source); + defer yaml.deinit(); + + const simple = try yaml.parse(struct { + a: struct { + b: []const u8, + c: []const u8, + }, + }); + try testing.expectEqualStrings("hello there", simple.a.b); + try testing.expectEqualStrings("wait, what?", simple.a.c); +} + +test "single quoted string" { + const source = + \\- 'hello' + \\- 'here''s an escaped quote' + \\- 'newlines and tabs\nare not\tsupported' + ; + + var yaml = try Yaml.load(testing.allocator, source); + defer yaml.deinit(); + + const arr = try yaml.parse([3][]const u8); + try testing.expectEqual(arr.len, 3); + try testing.expectEqualStrings("hello", arr[0]); + try testing.expectEqualStrings("here's an escaped quote", arr[1]); + try testing.expectEqualStrings("newlines and tabs\\nare not\\tsupported", arr[2]); +} + +test "double quoted string" { + const source = + \\- "hello" + \\- "\"here\" are some escaped quotes" + \\- "newlines and tabs\nare\tsupported" + \\- "let's have + \\some fun!" + ; + + var yaml = try Yaml.load(testing.allocator, source); + defer yaml.deinit(); + + const arr = try yaml.parse([4][]const u8); + try testing.expectEqual(arr.len, 4); + try testing.expectEqualStrings("hello", arr[0]); + try testing.expectEqualStrings( + \\"here" are some escaped quotes + , arr[1]); + try testing.expectEqualStrings( + \\newlines and tabs + \\are supported + , arr[2]); + try testing.expectEqualStrings( + \\let's have + \\some fun! + , arr[3]); +} + +test "multidoc typed as a slice of structs" { + const source = + \\--- + \\a: 0 + \\--- + \\a: 1 + \\... + ; + + var yaml = try Yaml.load(testing.allocator, source); + defer yaml.deinit(); + + { + const result = try yaml.parse([2]struct { a: usize }); + try testing.expectEqual(result.len, 2); + try testing.expectEqual(result[0].a, 0); + try testing.expectEqual(result[1].a, 1); + } + + { + const result = try yaml.parse([]struct { a: usize }); + try testing.expectEqual(result.len, 2); + try testing.expectEqual(result[0].a, 0); + try testing.expectEqual(result[1].a, 1); + } +} + +test "multidoc typed as a struct is an error" { + const source = + \\--- + \\a: 0 + \\--- + \\b: 1 + \\... + ; + + var yaml = try Yaml.load(testing.allocator, source); + defer yaml.deinit(); + + try testing.expectError(Yaml.Error.TypeMismatch, yaml.parse(struct { a: usize })); + try testing.expectError(Yaml.Error.TypeMismatch, yaml.parse(struct { b: usize })); + try testing.expectError(Yaml.Error.TypeMismatch, yaml.parse(struct { a: usize, b: usize })); +} + +test "multidoc typed as a slice of structs with optionals" { + const source = + \\--- + \\a: 0 + \\c: 1.0 + \\--- + \\a: 1 + \\b: different field + \\... + ; + + var yaml = try Yaml.load(testing.allocator, source); + defer yaml.deinit(); + + const result = try yaml.parse([]struct { a: usize, b: ?[]const u8, c: ?f16 }); + try testing.expectEqual(result.len, 2); + + try testing.expectEqual(result[0].a, 0); + try testing.expect(result[0].b == null); + try testing.expect(result[0].c != null); + try testing.expectEqual(result[0].c.?, 1.0); + + try testing.expectEqual(result[1].a, 1); + try testing.expect(result[1].b != null); + try testing.expectEqualStrings("different field", result[1].b.?); + try testing.expect(result[1].c == null); +} + +test "empty yaml can be represented as void" { + const source = ""; + var yaml = try Yaml.load(testing.allocator, source); + defer yaml.deinit(); + const result = try yaml.parse(void); + try testing.expect(@TypeOf(result) == void); +} + +test "nonempty yaml cannot be represented as void" { + const source = + \\a: b + ; + + var yaml = try Yaml.load(testing.allocator, source); + defer yaml.deinit(); + + try testing.expectError(Yaml.Error.TypeMismatch, yaml.parse(void)); +} + +test "typed array size mismatch" { + const source = + \\- 0 + \\- 0 + ; + + var yaml = try Yaml.load(testing.allocator, source); + defer yaml.deinit(); + + try testing.expectError(Yaml.Error.ArraySizeMismatch, yaml.parse([1]usize)); + try testing.expectError(Yaml.Error.ArraySizeMismatch, yaml.parse([5]usize)); +} + +test "comments" { + const source = + \\ + \\key: # this is the key + \\# first value + \\ + \\- val1 + \\ + \\# second value + \\- val2 + ; + + var yaml = try Yaml.load(testing.allocator, source); + defer yaml.deinit(); + + const simple = try yaml.parse(struct { + key: []const []const u8, + }); + try testing.expect(simple.key.len == 2); + try testing.expectEqualStrings("val1", simple.key[0]); + try testing.expectEqualStrings("val2", simple.key[1]); +} + +test "promote ints to floats in a list mixed numeric types" { + const source = + \\a_list: [0, 1.0] + ; + + var yaml = try Yaml.load(testing.allocator, source); + defer yaml.deinit(); + + const simple = try yaml.parse(struct { + a_list: []const f64, + }); + try testing.expectEqualSlices(f64, &[_]f64{ 0.0, 1.0 }, simple.a_list); +} + +test "demoting floats to ints in a list is an error" { + const source = + \\a_list: [0, 1.0] + ; + + var yaml = try Yaml.load(testing.allocator, source); + defer yaml.deinit(); + + try testing.expectError(error.TypeMismatch, yaml.parse(struct { + a_list: []const u64, + })); +} + +test "duplicate map keys" { + const source = + \\a: b + \\a: c + ; + try testing.expectError(error.DuplicateMapKey, Yaml.load(testing.allocator, source)); +} + +fn testStringify(expected: []const u8, input: anytype) !void { + var output = std.ArrayList(u8).init(testing.allocator); + defer output.deinit(); + + try yaml_mod.stringify(testing.allocator, input, output.writer()); + try testing.expectEqualStrings(expected, output.items); +} + +test "stringify an int" { + try testStringify("128", @as(u32, 128)); +} + +test "stringify a simple struct" { + try testStringify( + \\a: 1 + \\b: 2 + \\c: 2.5 + , struct { a: i64, b: f64, c: f64 }{ .a = 1, .b = 2.0, .c = 2.5 }); +} + +test "stringify a struct with an optional" { + try testStringify( + \\a: 1 + \\b: 2 + \\c: 2.5 + , struct { a: i64, b: ?f64, c: f64 }{ .a = 1, .b = 2.0, .c = 2.5 }); + + try testStringify( + \\a: 1 + \\c: 2.5 + , struct { a: i64, b: ?f64, c: f64 }{ .a = 1, .b = null, .c = 2.5 }); +} + +test "stringify a struct with all optionals" { + try testStringify("", struct { a: ?i64, b: ?f64 }{ .a = null, .b = null }); +} + +test "stringify an optional" { + try testStringify("", null); + try testStringify("", @as(?u64, null)); +} + +test "stringify a union" { + const Dummy = union(enum) { + x: u64, + y: f64, + }; + try testStringify("a: 1", struct { a: Dummy }{ .a = .{ .x = 1 } }); + try testStringify("a: 2.1", struct { a: Dummy }{ .a = .{ .y = 2.1 } }); +} + +test "stringify a string" { + try testStringify("a: name", struct { a: []const u8 }{ .a = "name" }); + try testStringify("name", "name"); +} + +test "stringify a list" { + try testStringify("[ 1, 2, 3 ]", @as([]const u64, &.{ 1, 2, 3 })); + try testStringify("[ 1, 2, 3 ]", .{ @as(i64, 1), 2, 3 }); + try testStringify("[ 1, name, 3 ]", .{ 1, "name", 3 }); + + const arr: [3]i64 = .{ 1, 2, 3 }; + try testStringify("[ 1, 2, 3 ]", arr); +} |
