|
1 | 1 | package xmlrpc |
2 | 2 |
|
3 | 3 | import ( |
| 4 | + "errors" |
4 | 5 | "fmt" |
5 | 6 | "strings" |
6 | 7 | "testing" |
@@ -579,3 +580,71 @@ func Test_encodeMap(t *testing.T) { |
579 | 580 | }) |
580 | 581 | } |
581 | 582 | } |
| 583 | + |
| 584 | +func Test_encodeTime_withTimeFormatter(t *testing.T) { |
| 585 | + input := time.Date(2019, 10, 11, 13, 40, 30, 0, time.UTC) |
| 586 | + |
| 587 | + tests := []struct { |
| 588 | + name string |
| 589 | + encoder *StdEncoder |
| 590 | + expect string |
| 591 | + }{ |
| 592 | + { |
| 593 | + name: "unset formatter retains RFC3339", |
| 594 | + encoder: &StdEncoder{}, |
| 595 | + expect: "<dateTime.iso8601>2019-10-11T13:40:30Z</dateTime.iso8601>", |
| 596 | + }, |
| 597 | + { |
| 598 | + name: "custom formatter", |
| 599 | + encoder: &StdEncoder{ |
| 600 | + timeFormatter: &LayoutTimeFormatter{FormatLayout: LayoutISO8601Compact}, |
| 601 | + }, |
| 602 | + expect: "<dateTime.iso8601>20191011T13:40:30</dateTime.iso8601>", |
| 603 | + }, |
| 604 | + } |
| 605 | + |
| 606 | + for _, tt := range tests { |
| 607 | + t.Run(tt.name, func(t *testing.T) { |
| 608 | + buf := new(strings.Builder) |
| 609 | + require.NoError(t, tt.encoder.encodeTime(buf, input)) |
| 610 | + require.Equal(t, tt.expect, buf.String()) |
| 611 | + }) |
| 612 | + } |
| 613 | +} |
| 614 | + |
| 615 | +// failingWriter fails once more than limit bytes have been written, so a failure can be |
| 616 | +// injected at any point of an element. |
| 617 | +type failingWriter struct { |
| 618 | + limit int |
| 619 | + written int |
| 620 | +} |
| 621 | + |
| 622 | +func (w *failingWriter) Write(p []byte) (int, error) { |
| 623 | + if w.written+len(p) > w.limit { |
| 624 | + return 0, errors.New("write failed") |
| 625 | + } |
| 626 | + w.written += len(p) |
| 627 | + |
| 628 | + return len(p), nil |
| 629 | +} |
| 630 | + |
| 631 | +func Test_encodeTime_writerErrors(t *testing.T) { |
| 632 | + input := time.Date(2019, 10, 11, 13, 40, 30, 0, time.UTC) |
| 633 | + |
| 634 | + // Full output is "<dateTime.iso8601>2019-10-11T13:40:30Z</dateTime.iso8601>" |
| 635 | + tests := []struct { |
| 636 | + name string |
| 637 | + limit int |
| 638 | + }{ |
| 639 | + {name: "fails on opening tag", limit: 0}, |
| 640 | + {name: "fails on value", limit: len("<dateTime.iso8601>")}, |
| 641 | + {name: "fails on closing tag", limit: len("<dateTime.iso8601>2019-10-11T13:40:30Z")}, |
| 642 | + } |
| 643 | + |
| 644 | + for _, tt := range tests { |
| 645 | + t.Run(tt.name, func(t *testing.T) { |
| 646 | + err := (&StdEncoder{}).encodeTime(&failingWriter{limit: tt.limit}, input) |
| 647 | + require.Error(t, err, "writer failure must not be discarded") |
| 648 | + }) |
| 649 | + } |
| 650 | +} |
0 commit comments