|
|
|
package acedoc
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
|
|
|
"testing"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestDelta2(t *testing.T) {
|
|
|
|
src := `
|
|
|
|
[
|
|
|
|
{
|
|
|
|
"delta": {
|
|
|
|
"start": {
|
|
|
|
"row": 0,
|
|
|
|
"column": 0
|
|
|
|
},
|
|
|
|
"end": {
|
|
|
|
"row": 0,
|
|
|
|
"column": 1
|
|
|
|
},
|
|
|
|
"action": "insert",
|
|
|
|
"lines": [
|
|
|
|
"a"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
"after": "a"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"delta": {
|
|
|
|
"start": {
|
|
|
|
"row": 0,
|
|
|
|
"column": 1
|
|
|
|
},
|
|
|
|
"end": {
|
|
|
|
"row": 0,
|
|
|
|
"column": 2
|
|
|
|
},
|
|
|
|
"action": "insert",
|
|
|
|
"lines": [
|
|
|
|
"b"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
"after": "ab"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"delta": {
|
|
|
|
"start": {
|
|
|
|
"row": 0,
|
|
|
|
"column": 2
|
|
|
|
},
|
|
|
|
"end": {
|
|
|
|
"row": 0,
|
|
|
|
"column": 3
|
|
|
|
},
|
|
|
|
"action": "insert",
|
|
|
|
"lines": [
|
|
|
|
"c"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
"after": "abc"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"delta": {
|
|
|
|
"start": {
|
|
|
|
"row": 0,
|
|
|
|
"column": 3
|
|
|
|
},
|
|
|
|
"end": {
|
|
|
|
"row": 0,
|
|
|
|
"column": 4
|
|
|
|
},
|
|
|
|
"action": "insert",
|
|
|
|
"lines": [
|
|
|
|
"d"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
"after": "abcd"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"delta": {
|
|
|
|
"start": {
|
|
|
|
"row": 0,
|
|
|
|
"column": 4
|
|
|
|
},
|
|
|
|
"end": {
|
|
|
|
"row": 0,
|
|
|
|
"column": 5
|
|
|
|
},
|
|
|
|
"action": "insert",
|
|
|
|
"lines": [
|
|
|
|
"e"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
"after": "abcde"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"delta": {
|
|
|
|
"start": {
|
|
|
|
"row": 0,
|
|
|
|
"column": 5
|
|
|
|
},
|
|
|
|
"end": {
|
|
|
|
"row": 0,
|
|
|
|
"column": 6
|
|
|
|
},
|
|
|
|
"action": "insert",
|
|
|
|
"lines": [
|
|
|
|
"f"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
"after": "abcdef"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"delta": {
|
|
|
|
"start": {
|
|
|
|
"row": 0,
|
|
|
|
"column": 2
|
|
|
|
},
|
|
|
|
"end": {
|
|
|
|
"row": 1,
|
|
|
|
"column": 0
|
|
|
|
},
|
|
|
|
"action": "insert",
|
|
|
|
"lines": [
|
|
|
|
"",
|
|
|
|
""
|
|
|
|
]
|
|
|
|
},
|
|
|
|
"after": "ab\ncdef"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"delta": {
|
|
|
|
"start": {
|
|
|
|
"row": 1,
|
|
|
|
"column": 0
|
|
|
|
},
|
|
|
|
"end": {
|
|
|
|
"row": 2,
|
|
|
|
"column": 0
|
|
|
|
},
|
|
|
|
"action": "insert",
|
|
|
|
"lines": [
|
|
|
|
"",
|
|
|
|
""
|
|
|
|
]
|
|
|
|
},
|
|
|
|
"after": "ab\n\ncdef"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"delta": {
|
|
|
|
"start": {
|
|
|
|
"row": 2,
|
|
|
|
"column": 1
|
|
|
|
},
|
|
|
|
"end": {
|
|
|
|
"row": 2,
|
|
|
|
"column": 2
|
|
|
|
},
|
|
|
|
"action": "remove",
|
|
|
|
"lines": [
|
|
|
|
"d"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
"after": "ab\n\ncef"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"delta": {
|
|
|
|
"start": {
|
|
|
|
"row": 0,
|
|
|
|
"column": 2
|
|
|
|
},
|
|
|
|
"end": {
|
|
|
|
"row": 1,
|
|
|
|
"column": 0
|
|
|
|
},
|
|
|
|
"action": "remove",
|
|
|
|
"lines": [
|
|
|
|
"",
|
|
|
|
""
|
|
|
|
]
|
|
|
|
},
|
|
|
|
"after": "ab\ncef"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"delta": {
|
|
|
|
"start": {
|
|
|
|
"row": 0,
|
|
|
|
"column": 0
|
|
|
|
},
|
|
|
|
"end": {
|
|
|
|
"row": 1,
|
|
|
|
"column": 0
|
|
|
|
},
|
|
|
|
"action": "insert",
|
|
|
|
"lines": [
|
|
|
|
"",
|
|
|
|
""
|
|
|
|
]
|
|
|
|
},
|
|
|
|
"after": "\nab\ncef"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"delta": {
|
|
|
|
"start": {
|
|
|
|
"row": 2,
|
|
|
|
"column": 3
|
|
|
|
},
|
|
|
|
"end": {
|
|
|
|
"row": 3,
|
|
|
|
"column": 0
|
|
|
|
},
|
|
|
|
"action": "insert",
|
|
|
|
"lines": [
|
|
|
|
"",
|
|
|
|
""
|
|
|
|
]
|
|
|
|
},
|
|
|
|
"after": "\nab\ncef\n"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"delta": {
|
|
|
|
"start": {
|
|
|
|
"row": 3,
|
|
|
|
"column": 0
|
|
|
|
},
|
|
|
|
"end": {
|
|
|
|
"row": 3,
|
|
|
|
"column": 1
|
|
|
|
},
|
|
|
|
"action": "insert",
|
|
|
|
"lines": [
|
|
|
|
"m"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
"after": "\nab\ncef\nm"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"delta": {
|
|
|
|
"start": {
|
|
|
|
"row": 2,
|
|
|
|
"column": 0
|
|
|
|
},
|
|
|
|
"end": {
|
|
|
|
"row": 2,
|
|
|
|
"column": 1
|
|
|
|
},
|
|
|
|
"action": "remove",
|
|
|
|
"lines": [
|
|
|
|
"c"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
"after": "\nab\nef\nm"
|
|
|
|
}
|
|
|
|
]
|
|
|
|
|
|
|
|
`
|
|
|
|
|
|
|
|
type c struct {
|
|
|
|
After string
|
|
|
|
Delta Delta
|
|
|
|
}
|
|
|
|
|
|
|
|
cases := []c{}
|
|
|
|
err := json.Unmarshal([]byte(src), &cases)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
doc := NewString("")
|
|
|
|
for i, c := range cases {
|
|
|
|
t.Run(fmt.Sprint(i), func(t *testing.T) {
|
|
|
|
before := doc.Contents()
|
|
|
|
|
|
|
|
err := doc.Apply(c.Delta)
|
|
|
|
if err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if doc.Contents() != c.After {
|
|
|
|
t.Errorf("unexpected output after applying delta %q: %q -> %q, expected: %q", c.Delta, before, doc.Contents(), c.After)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestDelta(t *testing.T) {
|
|
|
|
type c struct {
|
|
|
|
name string
|
|
|
|
start string
|
|
|
|
expect string
|
|
|
|
delta Delta
|
|
|
|
}
|
|
|
|
|
|
|
|
cases := []c{
|
|
|
|
|
|
|
|
// empty tests
|
|
|
|
|
|
|
|
{"empty",
|
|
|
|
"", "", Delta{}},
|
|
|
|
|
|
|
|
{"empty with content",
|
|
|
|
"a", "a", Delta{}},
|
|
|
|
|
|
|
|
// insert tests
|
|
|
|
|
|
|
|
{"insert with no content",
|
|
|
|
"a", "a", Insert(0, 1, "")},
|
|
|
|
|
|
|
|
{"insert",
|
|
|
|
"a", "ab", Insert(0, 1, "b")},
|
|
|
|
|
|
|
|
{"insert across line",
|
|
|
|
"a", "a\nb", Insert(0, 1, "\nb")},
|
|
|
|
|
|
|
|
{"insert new line",
|
|
|
|
"ab", "a\nb", Insert(0, 1, "\n")},
|
|
|
|
|
|
|
|
{"insert lines at beginning",
|
|
|
|
"ab", "\n\nab", Insert(0, 0, "\n\n")},
|
|
|
|
|
|
|
|
{"insert lines at end",
|
|
|
|
"ab", "ab\n\n", Insert(0, 2, "\n\n")},
|
|
|
|
|
|
|
|
{"insert more lines",
|
|
|
|
"a\nb", "a\n\n\nb", Insert(0, 1, "\n\n")},
|
|
|
|
|
|
|
|
// remove tests
|
|
|
|
{"remove",
|
|
|
|
"a", "", Remove(0, 0, "a")},
|
|
|
|
|
|
|
|
{"remove part",
|
|
|
|
"aa", "a", Remove(0, 0, "a")},
|
|
|
|
|
|
|
|
{"remove other part",
|
|
|
|
"aa", "a", Remove(0, 1, "a")},
|
|
|
|
|
|
|
|
{"remove across line",
|
|
|
|
"a\nb", "a", Remove(0, 1, "\nb")},
|
|
|
|
|
|
|
|
{"remove across two lines",
|
|
|
|
"a\nb\nc", "ac", Remove(0, 1, "\nb\n")},
|
|
|
|
|
|
|
|
{"remove all across line",
|
|
|
|
"a\nb", "", Remove(0, 0, "a\nb")},
|
|
|
|
|
|
|
|
{"remove all across two lines",
|
|
|
|
"a\nb\nc", "", Remove(0, 0, "a\nb\nc")},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, c := range cases {
|
|
|
|
t.Run(c.name, func(t *testing.T) {
|
|
|
|
doc := NewString(c.start)
|
|
|
|
err := doc.Apply(c.delta)
|
|
|
|
if err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if doc.Contents() != c.expect {
|
|
|
|
t.Errorf("unexpected output: %q, expected: %q", doc.Contents(), c.expect)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|