|
1 | 1 | package excelize |
2 | 2 |
|
3 | 3 | import ( |
| 4 | + "bytes" |
4 | 5 | "encoding/xml" |
5 | 6 | "fmt" |
6 | 7 | "io" |
@@ -532,3 +533,175 @@ func TestStreamWriterGetRowElement(t *testing.T) { |
532 | 533 | assert.False(t, ok) |
533 | 534 | } |
534 | 535 | } |
| 536 | + |
| 537 | +func TestBufferedWriterWriteInt(t *testing.T) { |
| 538 | + // In-memory path |
| 539 | + bw := &bufferedWriter{flushSize: StreamChunkSize, bioSize: StreamingBufSizeDefault} |
| 540 | + bw.WriteInt(42) |
| 541 | + bw.WriteInt(-1234567890) |
| 542 | + assert.Equal(t, "42-1234567890", bw.buf.String()) |
| 543 | + assert.Equal(t, int64(len("42-1234567890")), bw.written) |
| 544 | + |
| 545 | + // Temp file (bio) path |
| 546 | + bw2 := &bufferedWriter{flushSize: 1, bioSize: 4096} |
| 547 | + bw2.WriteString("x") // trigger sync |
| 548 | + _ = bw2.Sync() |
| 549 | + assert.NotNil(t, bw2.bio) |
| 550 | + bw2.WriteInt(99) |
| 551 | + _ = bw2.Flush() |
| 552 | + bw2.tmp.Seek(0, 0) |
| 553 | + data, _ := io.ReadAll(bw2.tmp) |
| 554 | + assert.Contains(t, string(data), "99") |
| 555 | + bw2.Close() |
| 556 | +} |
| 557 | + |
| 558 | +func TestBufferedWriterWriteUint(t *testing.T) { |
| 559 | + bw := &bufferedWriter{flushSize: StreamChunkSize, bioSize: StreamingBufSizeDefault} |
| 560 | + bw.WriteUint(12345) |
| 561 | + assert.Equal(t, "12345", bw.buf.String()) |
| 562 | + |
| 563 | + // bio path |
| 564 | + bw2 := &bufferedWriter{flushSize: 1, bioSize: 4096} |
| 565 | + bw2.WriteString("x") |
| 566 | + _ = bw2.Sync() |
| 567 | + bw2.WriteUint(67890) |
| 568 | + _ = bw2.Flush() |
| 569 | + bw2.tmp.Seek(0, 0) |
| 570 | + data, _ := io.ReadAll(bw2.tmp) |
| 571 | + assert.Contains(t, string(data), "67890") |
| 572 | + bw2.Close() |
| 573 | +} |
| 574 | + |
| 575 | +func TestBufferedWriterWriteFloat(t *testing.T) { |
| 576 | + bw := &bufferedWriter{flushSize: StreamChunkSize, bioSize: StreamingBufSizeDefault} |
| 577 | + bw.WriteFloat(3.14, 'f', 2, 64) |
| 578 | + assert.Equal(t, "3.14", bw.buf.String()) |
| 579 | + |
| 580 | + // bio path |
| 581 | + bw2 := &bufferedWriter{flushSize: 1, bioSize: 4096} |
| 582 | + bw2.WriteString("x") |
| 583 | + _ = bw2.Sync() |
| 584 | + bw2.WriteFloat(2.72, 'f', 2, 64) |
| 585 | + _ = bw2.Flush() |
| 586 | + bw2.tmp.Seek(0, 0) |
| 587 | + data, _ := io.ReadAll(bw2.tmp) |
| 588 | + assert.Contains(t, string(data), "2.72") |
| 589 | + bw2.Close() |
| 590 | +} |
| 591 | + |
| 592 | +func TestBufferedWriterBytes(t *testing.T) { |
| 593 | + // In-memory: returns buffer bytes |
| 594 | + bw := &bufferedWriter{flushSize: StreamChunkSize, bioSize: StreamingBufSizeDefault} |
| 595 | + bw.WriteString("hello") |
| 596 | + assert.Equal(t, []byte("hello"), bw.Bytes()) |
| 597 | + |
| 598 | + // After temp file creation: returns nil |
| 599 | + bw2 := &bufferedWriter{flushSize: 1, bioSize: 4096} |
| 600 | + bw2.WriteString("x") |
| 601 | + _ = bw2.Sync() |
| 602 | + assert.Nil(t, bw2.Bytes()) |
| 603 | + bw2.Close() |
| 604 | +} |
| 605 | + |
| 606 | +func TestBufferedWriterWriteAt(t *testing.T) { |
| 607 | + // In-memory WriteAt |
| 608 | + bw := &bufferedWriter{flushSize: StreamChunkSize, bioSize: StreamingBufSizeDefault} |
| 609 | + bw.WriteString("AAABBBCCC") |
| 610 | + err := bw.WriteAt([]byte("XXX"), 3) |
| 611 | + assert.NoError(t, err) |
| 612 | + assert.Equal(t, "AAAXXXCCC", bw.buf.String()) |
| 613 | + |
| 614 | + // In-memory WriteAt out of bounds |
| 615 | + err = bw.WriteAt([]byte("TOOLONG"), 5) |
| 616 | + assert.Error(t, err) |
| 617 | + |
| 618 | + // Temp file WriteAt |
| 619 | + bw2 := &bufferedWriter{flushSize: 1, bioSize: 4096} |
| 620 | + bw2.WriteString("AAABBBCCC") |
| 621 | + _ = bw2.Sync() |
| 622 | + err = bw2.WriteAt([]byte("YYY"), 3) |
| 623 | + assert.NoError(t, err) |
| 624 | + // Verify by reading the file back |
| 625 | + var readBuf bytes.Buffer |
| 626 | + _, _ = bw2.CopyTo(&readBuf) |
| 627 | + assert.Equal(t, "AAAYYYCC", readBuf.String()[:8]) |
| 628 | + bw2.Close() |
| 629 | +} |
| 630 | + |
| 631 | +func TestBufferedWriterCopyTo(t *testing.T) { |
| 632 | + // In-memory CopyTo |
| 633 | + bw := &bufferedWriter{flushSize: StreamChunkSize, bioSize: StreamingBufSizeDefault} |
| 634 | + bw.WriteString("hello world") |
| 635 | + var dst bytes.Buffer |
| 636 | + n, err := bw.CopyTo(&dst) |
| 637 | + assert.NoError(t, err) |
| 638 | + assert.Equal(t, int64(11), n) |
| 639 | + assert.Equal(t, "hello world", dst.String()) |
| 640 | + |
| 641 | + // Temp file CopyTo |
| 642 | + bw2 := &bufferedWriter{flushSize: 1, bioSize: 4096} |
| 643 | + bw2.WriteString("file data here") |
| 644 | + _ = bw2.Sync() |
| 645 | + bw2.WriteString(" more") // this goes through bio |
| 646 | + var dst2 bytes.Buffer |
| 647 | + n2, err := bw2.CopyTo(&dst2) |
| 648 | + assert.NoError(t, err) |
| 649 | + assert.Equal(t, int64(19), n2) |
| 650 | + assert.Equal(t, "file data here more", dst2.String()) |
| 651 | + bw2.Close() |
| 652 | + |
| 653 | + // Temp file CopyTo with large bioSize (> 256KB) |
| 654 | + bw3 := &bufferedWriter{flushSize: 1, bioSize: 512 * 1024} |
| 655 | + bw3.WriteString("large buffer test") |
| 656 | + _ = bw3.Sync() |
| 657 | + var dst3 bytes.Buffer |
| 658 | + n3, err := bw3.CopyTo(&dst3) |
| 659 | + assert.NoError(t, err) |
| 660 | + assert.Equal(t, int64(17), n3) |
| 661 | + assert.Equal(t, "large buffer test", dst3.String()) |
| 662 | + bw3.Close() |
| 663 | +} |
| 664 | + |
| 665 | +func TestBufferedWriterReset(t *testing.T) { |
| 666 | + // Reset in-memory only |
| 667 | + bw := &bufferedWriter{flushSize: StreamChunkSize, bioSize: StreamingBufSizeDefault} |
| 668 | + bw.WriteString("data") |
| 669 | + bw.Reset() |
| 670 | + assert.Equal(t, 0, bw.buf.Len()) |
| 671 | + |
| 672 | + // Reset after temp file creation |
| 673 | + bw2 := &bufferedWriter{flushSize: 1, bioSize: 4096} |
| 674 | + bw2.WriteString("data") |
| 675 | + _ = bw2.Sync() |
| 676 | + assert.NotNil(t, bw2.bio) |
| 677 | + bw2.Reset() |
| 678 | + assert.Nil(t, bw2.bio) |
| 679 | + assert.Equal(t, 0, bw2.buf.Len()) |
| 680 | + bw2.Close() |
| 681 | +} |
| 682 | + |
| 683 | +func TestNewStreamWriterOptions(t *testing.T) { |
| 684 | + // Test StreamingChunkSize = -1 (never spill) |
| 685 | + f := NewFile() |
| 686 | + defer f.Close() |
| 687 | + f.options.StreamingChunkSize = -1 |
| 688 | + sw, err := f.NewStreamWriter("Sheet1") |
| 689 | + assert.NoError(t, err) |
| 690 | + assert.True(t, sw.rawData.flushSize > StreamChunkSize) |
| 691 | + |
| 692 | + // Test StreamingBufSize custom value |
| 693 | + f2 := NewFile() |
| 694 | + defer f2.Close() |
| 695 | + f2.options.StreamingBufSize = 64 * 1024 |
| 696 | + sw2, err := f2.NewStreamWriter("Sheet1") |
| 697 | + assert.NoError(t, err) |
| 698 | + assert.Equal(t, 64*1024, sw2.rawData.bioSize) |
| 699 | + |
| 700 | + // Test StreamingChunkSize positive custom value |
| 701 | + f3 := NewFile() |
| 702 | + defer f3.Close() |
| 703 | + f3.options.StreamingChunkSize = 1024 |
| 704 | + sw3, err := f3.NewStreamWriter("Sheet1") |
| 705 | + assert.NoError(t, err) |
| 706 | + assert.Equal(t, 1024, sw3.rawData.flushSize) |
| 707 | +} |
0 commit comments