zls/tests/utility/offsets.zig
Techatrix e28549fa7d
Completely overhaul offsets.zig (#643)
* completely overhaul offsets.zig
2022-09-16 00:33:49 +00:00

170 lines
7.7 KiB
Zig

const std = @import("std");
const zls = @import("zls");
const types = zls.types;
const offsets = zls.offsets;
test "offsets - index <-> Position" {
try testIndexPosition("", 0, 0, .{ 0, 0, 0 });
try testIndexPosition("hello from zig", 10, 0, .{ 10, 10, 10 });
try testIndexPosition("\n", 0, 0, .{ 0, 0, 0 });
try testIndexPosition("\n", 1, 1, .{ 0, 0, 0 });
try testIndexPosition("hello\nfrom\nzig\n", 5, 0, .{ 5, 5, 5 });
try testIndexPosition("hello\nfrom\nzig\n", 6, 1, .{ 0, 0, 0 });
try testIndexPosition("hello\nfrom\nzig\n", 8, 1, .{ 2, 2, 2 });
try testIndexPosition("\nhello\nfrom\nzig", 15, 3, .{ 3, 3, 3 });
try testIndexPosition("a¶↉🠁", 10, 0, .{ 10, 5, 4 });
try testIndexPosition("🇺🇸 🇩🇪", 17, 0, .{ 17, 9, 5 });
try testIndexPosition("a¶↉🠁\na¶↉🠁", 10, 0, .{ 10, 5, 4 });
try testIndexPosition("a¶↉🠁\na¶↉🠁", 11, 1, .{ 0, 0, 0 });
try testIndexPosition("a¶↉🠁\na¶↉🠁", 21, 1, .{ 10, 5, 4 });
try testIndexPosition("\na¶↉🠁", 4, 1, .{ 3, 2, 2 });
try testIndexPosition("a¶↉🠁\n", 6, 0, .{ 6, 3, 3 });
try testIndexPosition("a¶↉🠁\n", 11, 1, .{ 0, 0, 0 });
}
test "offsets - tokenToLoc" {
try testTokenToLoc("foo", 0, 0, 3);
try testTokenToLoc("foo\n", 0, 0, 3);
try testTokenToLoc("\nfoo", 0, 1, 4);
try testTokenToLoc("foo:", 0, 0, 3);
try testTokenToLoc(";;", 1, 1, 2);
}
test "offsets - tokenIndexToLoc" {
try testTokenIndexToLoc("", 0, 0, 0);
try testTokenIndexToLoc("foo", 0, 0, 3);
try testTokenIndexToLoc("0, 0", 3, 3, 4);
try testTokenIndexToLoc(" bar ", 0, 1, 4);
}
test "offsets - lineLocAtIndex" {
try std.testing.expectEqualStrings("", offsets.lineSliceAtIndex("", 0));
try std.testing.expectEqualStrings("", offsets.lineSliceAtIndex("\n", 0));
try std.testing.expectEqualStrings("", offsets.lineSliceAtIndex("\n", 1));
try std.testing.expectEqualStrings("foo", offsets.lineSliceAtIndex("foo\nbar", 2));
try std.testing.expectEqualStrings("bar", offsets.lineSliceAtIndex("foo\nbar", 4));
try std.testing.expectEqualStrings("bar", offsets.lineSliceAtIndex("foo\nbar", 6));
try std.testing.expectEqualStrings("", offsets.lineSliceAtIndex("foo\n", 4));
try std.testing.expectEqualStrings("foo", offsets.lineSliceAtIndex("foo\n", 3));
}
test "offsets - lineLocUntilIndex" {
try std.testing.expectEqualStrings("", offsets.lineSliceUntilIndex("", 0));
try std.testing.expectEqualStrings("", offsets.lineSliceUntilIndex("\n", 0));
try std.testing.expectEqualStrings("", offsets.lineSliceUntilIndex("\n", 1));
try std.testing.expectEqualStrings("fo", offsets.lineSliceUntilIndex("foo\nbar", 2));
try std.testing.expectEqualStrings("", offsets.lineSliceUntilIndex("foo\nbar", 4));
try std.testing.expectEqualStrings("ba", offsets.lineSliceUntilIndex("foo\nbar", 6));
try std.testing.expectEqualStrings("", offsets.lineSliceUntilIndex("foo\n", 4));
try std.testing.expectEqualStrings("foo", offsets.lineSliceUntilIndex("foo\n", 3));
}
test "offsets - convertPositionEncoding" {
try testConvertPositionEncoding("", 0, 0, .{ 0, 0, 0 });
try testConvertPositionEncoding("\n", 0, 0, .{ 0, 0, 0 });
try testConvertPositionEncoding("\n", 1, 0, .{ 0, 0, 0 });
try testConvertPositionEncoding("foo", 0, 3, .{ 3, 3, 3 });
try testConvertPositionEncoding("a¶↉🠁", 0, 10, .{ 10, 5, 4 });
try testConvertPositionEncoding("a¶↉🠁\na¶↉🠁", 1, 6, .{ 6, 3, 3 });
}
test "offsets - advancePosition" {
try testAdvancePosition("", 0, 0, 0, 0, 0, 0);
try testAdvancePosition("foo", 0, 3, 0, 0, 0, 3);
try testAdvancePosition("\n", 1, 0, 0, 0, 0, 1);
try testAdvancePosition("foo\nbar", 1, 2, 0, 1, 1, 6);
try testAdvancePosition("foo\nbar", 1, 3, 1, 0, 4, 7);
}
test "offsets - countCodeUnits" {
try testCountCodeUnits("", .{ 0, 0, 0 });
try testCountCodeUnits("a\na", .{ 3, 3, 3 });
try testCountCodeUnits("a¶↉🠁", .{ 10, 5, 4 });
try testCountCodeUnits("🠁↉¶a", .{ 10, 5, 4 });
try testCountCodeUnits("🇺🇸 🇩🇪", .{ 17, 9, 5 });
}
test "offsets - getNCodeUnitByteCount" {
try testGetNCodeUnitByteCount("", .{ 0, 0, 0 });
try testGetNCodeUnitByteCount("foo", .{ 2, 2, 2 });
try testGetNCodeUnitByteCount("a¶🠁🠁", .{ 7, 4, 3 });
try testGetNCodeUnitByteCount("🇺🇸 🇩🇪", .{ 9, 5, 3 });
}
fn testIndexPosition(text: []const u8, index: usize, line: u32, characters: [3]u32) !void {
const position8: types.Position = .{ .line = line, .character = characters[0] };
const position16: types.Position = .{ .line = line, .character = characters[1] };
const position32: types.Position = .{ .line = line, .character = characters[2] };
try std.testing.expectEqual(position8, offsets.indexToPosition(text, index, .utf8));
try std.testing.expectEqual(position16, offsets.indexToPosition(text, index, .utf16));
try std.testing.expectEqual(position32, offsets.indexToPosition(text, index, .utf32));
try std.testing.expectEqual(index, offsets.positionToIndex(text, position8, .utf8));
try std.testing.expectEqual(index, offsets.positionToIndex(text, position16, .utf16));
try std.testing.expectEqual(index, offsets.positionToIndex(text, position32, .utf32));
}
fn testTokenToLoc(text: [:0]const u8, token_index: std.zig.Ast.TokenIndex, start: usize, end: usize) !void {
var tree = try std.zig.parse(std.testing.allocator, text);
defer tree.deinit(std.testing.allocator);
const actual = offsets.tokenToLoc(tree, token_index);
try std.testing.expectEqual(start, actual.start);
try std.testing.expectEqual(end, actual.end);
}
fn testTokenIndexToLoc(text: [:0]const u8, index: usize, start: usize, end: usize) !void {
const loc = offsets.tokenIndexToLoc(text, index);
try std.testing.expectEqual(start, loc.start);
try std.testing.expectEqual(end, loc.end);
}
fn testAdvancePosition(text: [:0]const u8, expected_line: u32, expected_character: u32, line: u32, character: u32, from: usize, to: usize) !void {
const expected: types.Position = .{ .line = expected_line, .character = expected_character };
const actual = offsets.advancePosition(text, .{ .line = line, .character = character }, from, to, .utf16);
try std.testing.expectEqual(expected, actual);
}
fn testConvertPositionEncoding(text: [:0]const u8, line: u32, character: u32, new_characters: [3]u32) !void {
const position: types.Position = .{ .line = line, .character = character };
const position8 = offsets.convertPositionEncoding(text, position, .utf8, .utf8);
const position16 = offsets.convertPositionEncoding(text, position, .utf8, .utf16);
const position32 = offsets.convertPositionEncoding(text, position, .utf8, .utf32);
try std.testing.expectEqual(line, position8.line);
try std.testing.expectEqual(line, position16.line);
try std.testing.expectEqual(line, position32.line);
try std.testing.expectEqual(new_characters[0], position8.character);
try std.testing.expectEqual(new_characters[1], position16.character);
try std.testing.expectEqual(new_characters[2], position32.character);
}
fn testCountCodeUnits(text: []const u8, counts: [3]usize) !void {
try std.testing.expectEqual(counts[0], offsets.countCodeUnits(text, .utf8));
try std.testing.expectEqual(counts[1], offsets.countCodeUnits(text, .utf16));
try std.testing.expectEqual(counts[2], offsets.countCodeUnits(text, .utf32));
}
fn testGetNCodeUnitByteCount(text: []const u8, n: [3]usize) !void {
try std.testing.expectEqual(n[0], offsets.getNCodeUnitByteCount(text, n[0], .utf8));
try std.testing.expectEqual(n[0], offsets.getNCodeUnitByteCount(text, n[1], .utf16));
try std.testing.expectEqual(n[0], offsets.getNCodeUnitByteCount(text, n[2], .utf32));
}