Skip to content

Commit 4058ef4

Browse files
committed
Fix Preview Output Corruption for Custom PreviewWriter
Always wrap PreviewWriter with newlineWriter to ensure newlines. When a custom PreviewWriter is provided (like in the web app), preview output wasn't wrapped with newlineWriter, causing JSON records to be concatenated without newlines between them. This was especially noticeable with single records.
1 parent 476774c commit 4058ef4

2 files changed

Lines changed: 98 additions & 0 deletions

File tree

dryrun_test.go

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package batch
2+
3+
import (
4+
"bytes"
5+
"context"
6+
"strings"
7+
"testing"
8+
9+
force "github.com/ForceCLI/force/lib"
10+
)
11+
12+
func TestDryRunAddsNewlinesBetweenRecords(t *testing.T) {
13+
// Create a buffer to capture output
14+
var buf bytes.Buffer
15+
16+
// Create an execution with a custom PreviewWriter
17+
exec := &Execution{
18+
PreviewWriter: &buf,
19+
}
20+
21+
// Create a channel with test records
22+
records := make(chan force.ForceRecord, 2)
23+
records <- force.ForceRecord{"Id": "001000000000001", "Name": "Test Account 1"}
24+
records <- force.ForceRecord{"Id": "001000000000002", "Name": "Test Account 2"}
25+
close(records)
26+
27+
// Run dry run
28+
ctx := context.Background()
29+
_, err := exec.dryRun(ctx, records)
30+
if err != nil {
31+
t.Fatalf("dryRun returned error: %v", err)
32+
}
33+
34+
// Check output
35+
output := buf.String()
36+
lines := strings.Split(strings.TrimSpace(output), "\n")
37+
38+
// Should have exactly 2 lines
39+
if len(lines) != 2 {
40+
t.Errorf("Expected 2 lines, got %d. Output:\n%s", len(lines), output)
41+
}
42+
43+
// Each line should be valid JSON
44+
expectedLines := []string{
45+
`{"Id":"001000000000001","Name":"Test Account 1"}`,
46+
`{"Id":"001000000000002","Name":"Test Account 2"}`,
47+
}
48+
49+
for i, line := range lines {
50+
if line != expectedLines[i] {
51+
t.Errorf("Line %d mismatch:\nExpected: %s\nGot: %s", i+1, expectedLines[i], line)
52+
}
53+
}
54+
}
55+
56+
func TestDryRunWithSingleRecord(t *testing.T) {
57+
// Create a buffer to capture output
58+
var buf bytes.Buffer
59+
60+
// Create an execution with a custom PreviewWriter
61+
exec := &Execution{
62+
PreviewWriter: &buf,
63+
}
64+
65+
// Create a channel with a single test record
66+
records := make(chan force.ForceRecord, 1)
67+
records <- force.ForceRecord{"Id": "001000000000001", "Name": "Test Account"}
68+
close(records)
69+
70+
// Run dry run
71+
ctx := context.Background()
72+
_, err := exec.dryRun(ctx, records)
73+
if err != nil {
74+
t.Fatalf("dryRun returned error: %v", err)
75+
}
76+
77+
// Check output
78+
output := buf.String()
79+
80+
// Should end with a newline
81+
if !strings.HasSuffix(output, "\n") {
82+
t.Errorf("Output should end with a newline. Got: %q", output)
83+
}
84+
85+
// Should have exactly one line when trimmed
86+
trimmed := strings.TrimSpace(output)
87+
if strings.Contains(trimmed, "\n") {
88+
t.Errorf("Output should contain only one record. Got: %q", output)
89+
}
90+
91+
// Should be valid JSON
92+
expected := `{"Id":"001000000000001","Name":"Test Account"}`
93+
if trimmed != expected {
94+
t.Errorf("Output mismatch:\nExpected: %s\nGot: %s", expected, trimmed)
95+
}
96+
}

execution.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,8 @@ func (e *Execution) dryRun(ctx context.Context, records <-chan force.ForceRecord
303303
previewWriter := e.PreviewWriter
304304
if previewWriter == nil {
305305
previewWriter = newlineWriter{w: os.Stdout}
306+
} else {
307+
previewWriter = newlineWriter{w: previewWriter}
306308
}
307309

308310
waitForRecord := 5 * time.Second

0 commit comments

Comments
 (0)