-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapi_test.go
More file actions
243 lines (194 loc) · 7.12 KB
/
api_test.go
File metadata and controls
243 lines (194 loc) · 7.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
// api_test.go
// package editml_test contains unit tests for the editml API.
package editml
import (
"os" // For reading test files
"path/filepath" // For joining path elements
"reflect" // For deep equality comparison of slices and structs
"strings" // For string manipulations like TrimSpace
"testing"
"github.com/verkaro/editml-go/model"
)
// TestParseSimpleAddition tests the Parse function with a basic addition.
func TestParseSimpleAddition(t *testing.T) {
inputText := "{+added text+ws}"
expectedNodes := []model.Node{
model.InlineEditNode{
EditType: model.EditTypeAddition,
Content: "added text",
EditorID: "ws",
},
}
// For MVP, we expect no issues from this simple valid input.
expectedIssues := []Issue{}
actualNodes, actualIssues := Parse(inputText)
if !reflect.DeepEqual(actualNodes, expectedNodes) {
t.Errorf("Parse(%q) nodes = %v, want %v", inputText, actualNodes, expectedNodes)
}
if !reflect.DeepEqual(actualIssues, expectedIssues) {
t.Errorf("Parse(%q) issues = %v, want %v", inputText, actualIssues, expectedIssues)
}
}
// TestParseTextAndAddition tests parsing a mix of plain text and an addition.
func TestParseTextAndAddition(t *testing.T) {
inputText := "Hello {+World+}"
expectedNodes := []model.Node{
model.TextNode{Text: "Hello "},
model.InlineEditNode{EditType: model.EditTypeAddition, Content: "World", EditorID: ""},
}
expectedIssues := []Issue{}
actualNodes, actualIssues := Parse(inputText)
if !reflect.DeepEqual(actualNodes, expectedNodes) {
t.Errorf("Parse(%q) nodes = %v, want %v", inputText, actualNodes, expectedNodes)
}
if !reflect.DeepEqual(actualIssues, expectedIssues) {
t.Errorf("Parse(%q) issues = %v, want %v", inputText, actualIssues, expectedIssues)
}
}
// TestTransformSimpleAddition tests TransformCleanView with a parsed addition.
func TestTransformSimpleAddition(t *testing.T) {
inputNodes := []model.Node{
model.InlineEditNode{
EditType: model.EditTypeAddition,
Content: "added text",
EditorID: "ws",
},
}
expectedOutput := "added text"
// For MVP, we expect no issues from this simple valid transformation.
expectedIssues := []Issue{}
actualOutput, actualIssues := TransformCleanView(inputNodes)
if actualOutput != expectedOutput {
t.Errorf("TransformCleanView for simple addition: output = %q, want %q", actualOutput, expectedOutput)
}
if !reflect.DeepEqual(actualIssues, expectedIssues) {
t.Errorf("TransformCleanView for simple addition: issues = %v, want %v", actualIssues, expectedIssues)
}
}
// TestTransformTextAndDeletion tests a mix of text and a deletion.
func TestTransformTextAndDeletion(t *testing.T) {
// Simulate parsing "Hello {-World-}"
inputNodes := []model.Node{
model.TextNode{Text: "Hello "},
model.InlineEditNode{EditType: model.EditTypeDeletion, Content: "World", EditorID: ""},
}
expectedOutput := "Hello " // Deletion content is removed
expectedIssues := []Issue{}
actualOutput, actualIssues := TransformCleanView(inputNodes)
if actualOutput != expectedOutput {
t.Errorf("TransformCleanView for text and deletion: output = %q, want %q", actualOutput, expectedOutput)
}
if !reflect.DeepEqual(actualIssues, expectedIssues) {
t.Errorf("TransformCleanView for text and deletion: issues = %v, want %v", actualIssues, expectedIssues)
}
}
// TestParseAndTransformIntegration is a simple integration test.
func TestParseAndTransformIntegration(t *testing.T) {
inputText := "This is {+an addition+} and this is {-a deletion-}."
expectedOutput := "This is an addition and this is ."
nodes, parseIssues := Parse(inputText)
if len(parseIssues) > 0 {
t.Fatalf("Parse(%q) returned unexpected issues: %v", inputText, parseIssues)
}
output, transformIssues := TransformCleanView(nodes)
if len(transformIssues) > 0 {
t.Fatalf("TransformCleanView returned unexpected issues: %v", transformIssues)
}
if output != expectedOutput {
t.Errorf("ParseAndTransformIntegration: output = %q, want %q", output, expectedOutput)
}
}
// TestParseAndTransformMultilineFile tests parsing and transforming the multiline.md test file.
func TestParseAndTransformMultilineFile(t *testing.T) {
// Read the content of testdata/multiline.md
filePath := filepath.Join("testdata", "multiline.md")
inputBytes, err := os.ReadFile(filePath)
if err != nil {
t.Fatalf("Failed to read test file %s: %v", filePath, err)
}
inputText := string(inputBytes)
// This is the "Final Output (Clean View)" based on the AST interpretation and debug output,
// corrected to have:
// 1. Two blank lines after "This is a test document for multiline EditML features."
// 2. Three blank lines after "Now for structural edits...".
expectedMultilineOutput := `This is a test document for multiline EditML features.
First, some multiline inline additions:
This is a simple
addition spanning
multiple lines. an example.
Another one without an ID:
This is another
multiline addition.
It even has a blank line
in the middle..
Multiline deletions:
This text is and should be removed.
And one more:
.
Multiline comments:
Here is some text that we want to keep.
A comment with an escaped closing operator:
.
Multiline highlights:
Let's emphasize this
important section
of text. for review.
Another highlight:
This part
is also
highlighted..
Now for structural edits with multiline content.
Some text in between.
This is a block
to be copied.
Line 1
Line 2
Line 3
More text.
And here are the targets:
The moved text should appear here: This is a block of text
that is intended to be moved.
It has multiple lines.
It even contains an escaped tilde: ~ here.
.
The copied text should appear here: This is a block
to be copied.
Line 1
Line 2
Line 3.
And also here: This is a block
to be copied.
Line 1
Line 2
Line 3.
Mixing it up:
This is an added line
that also contains {-a nested
deletion (which should be literal text per spec 3.3.4)-}
and more added text..
A structural move with inline edits inside its content:
The target for the mixed content move:
This block will be moved.
It contains added text within the block
and also some .
This should all move together.
End of multiline tests.`
nodes, parseIssues := Parse(inputText)
if len(parseIssues) > 0 {
t.Fatalf("Parse for multiline.md returned unexpected issues: %v", parseIssues)
}
actualOutput, transformIssues := TransformCleanView(nodes)
if len(transformIssues) > 0 {
t.Fatalf("TransformCleanView for multiline.md returned unexpected issues: %v", transformIssues)
}
// Primary comparison: exact match.
if actualOutput != expectedMultilineOutput {
// Fallback comparison if exact match fails, to see if it's just trailing whitespace.
if strings.TrimSpace(actualOutput) != strings.TrimSpace(expectedMultilineOutput) {
t.Errorf("ParseAndTransformMultilineFile: output (trimmed) does not match expected (trimmed).\nExpected:\n%s\n\nActual:\n%s", expectedMultilineOutput, actualOutput)
} else {
// Content is the same after trimming, so it's likely a subtle leading/trailing whitespace or newline difference.
t.Errorf("ParseAndTransformMultilineFile: output matches expected when trimmed, but differs in exact whitespace/newlines.\nExpected:\n%s\n\nActual:\n%s", expectedMultilineOutput, actualOutput)
}
}
}