| ... | ... | @@ -638,3 +638,85 @@ pub fn extract(dest: Io.Dir, fr: *File.Reader, options: ExtractOptions) !void { |
| 638 | 638 | } |
| 639 | 639 | } |
| 640 | 640 | } |
| 641 | |
| 642 | const testing = std.testing; |
| 643 | |
| 644 | test "extractTo" { |
| 645 | const io = testing.io; |
| 646 | var tmp = testing.tmpDir(.{}); |
| 647 | defer tmp.cleanup(); |
| 648 | |
| 649 | try tmp.dir.writeFile(io, .{ |
| 650 | .sub_path = "test.zip", |
| 651 | .data = @embedFile("zip/testdata/test.zip"), |
| 652 | }); |
| 653 | |
| 654 | var file = try tmp.dir.openFile(io, "test.zip", .{}); |
| 655 | defer file.close(io); |
| 656 | var read_buf: [512]u8 = undefined; |
| 657 | var reader = file.reader(io, &read_buf); |
| 658 | |
| 659 | const Expected = struct { |
| 660 | contents: []const u8, |
| 661 | compression: CompressionMethod, |
| 662 | }; |
| 663 | const expected_map = std.StaticStringMap(Expected).initComptime(.{ |
| 664 | .{ "deflate.txt", Expected{ .contents = "aaaaaaaaaaaaaaaaaaaaaaaa\n", .compression = .deflate } }, |
| 665 | .{ "store.txt", Expected{ .contents = "hello world\n", .compression = .store } }, |
| 666 | .{ "dir/", Expected{ .contents = "", .compression = .store } }, |
| 667 | }); |
| 668 | |
| 669 | var iter = try Iterator.init(&reader); |
| 670 | var num_entries: usize = 0; |
| 671 | while (try iter.next()) |entry| { |
| 672 | var filename_buf: [256]u8 = undefined; |
| 673 | const filename = try entry.getFilename(&reader, &filename_buf, .{}); |
| 674 | const expected = expected_map.get(filename) orelse { |
| 675 | std.debug.print("found unexpected filename: {f}\n", .{std.ascii.hexEscape(filename, .lower)}); |
| 676 | return error.UnexpectedFilename; |
| 677 | }; |
| 678 | var buf: [256]u8 = undefined; |
| 679 | var w: Writer = .fixed(&buf); |
| 680 | try entry.extractTo(&reader, &w); |
| 681 | try testing.expectEqualStrings(expected.contents, w.buffered()); |
| 682 | try testing.expectEqual(expected.compression, entry.compression_method); |
| 683 | num_entries += 1; |
| 684 | } |
| 685 | try testing.expectEqual(expected_map.kvs.len, num_entries); |
| 686 | } |
| 687 | |
| 688 | test "output buffers too small" { |
| 689 | const io = testing.io; |
| 690 | var tmp = testing.tmpDir(.{}); |
| 691 | defer tmp.cleanup(); |
| 692 | |
| 693 | try tmp.dir.writeFile(io, .{ |
| 694 | .sub_path = "test.zip", |
| 695 | .data = @embedFile("zip/testdata/test.zip"), |
| 696 | }); |
| 697 | |
| 698 | var file = try tmp.dir.openFile(io, "test.zip", .{}); |
| 699 | defer file.close(io); |
| 700 | var read_buf: [512]u8 = undefined; |
| 701 | var reader = file.reader(io, &read_buf); |
| 702 | |
| 703 | var iter = try Iterator.init(&reader); |
| 704 | var num_entries: usize = 0; |
| 705 | while (try iter.next()) |entry| { |
| 706 | try testing.expectError( |
| 707 | error.ZipInsufficientBuffer, |
| 708 | entry.getFilename(&reader, &.{}, .{}), |
| 709 | ); |
| 710 | |
| 711 | if (entry.uncompressed_size <= 1) continue; |
| 712 | |
| 713 | var buf: [1]u8 = undefined; |
| 714 | var w: Writer = .fixed(&buf); |
| 715 | try testing.expectError( |
| 716 | error.WriteFailed, |
| 717 | entry.extractTo(&reader, &w), |
| 718 | ); |
| 719 | num_entries += 1; |
| 720 | } |
| 721 | try std.testing.expect(num_entries > 0); |
| 722 | } |