wip
This commit is contained in:
@@ -68,13 +68,13 @@ func (d Delta) nRows() uint {
|
||||
return r
|
||||
}
|
||||
|
||||
func (d Delta) rows() uint {
|
||||
r := d.End.Row - d.Start.Row
|
||||
func (d Delta) rows() int {
|
||||
r := int(d.End.Row) - int(d.Start.Row)
|
||||
return r
|
||||
}
|
||||
|
||||
func (d Delta) cols() uint {
|
||||
r := d.End.Column
|
||||
func (d Delta) cols() int {
|
||||
r := int(d.End.Column) - int(d.Start.Column)
|
||||
return r
|
||||
}
|
||||
|
||||
@@ -82,6 +82,10 @@ func (d *Document) Contents() string {
|
||||
d.mtx.RLock()
|
||||
defer d.mtx.RUnlock()
|
||||
|
||||
return d.contents()
|
||||
}
|
||||
|
||||
func (d *Document) contents() string {
|
||||
return strings.Join(d.lines, "\n")
|
||||
}
|
||||
|
||||
|
||||
+284
-1
@@ -1,7 +1,290 @@
|
||||
package acedoc
|
||||
|
||||
import "testing"
|
||||
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
|
||||
|
||||
@@ -2,6 +2,7 @@ package acedoc
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@@ -60,7 +61,6 @@ func (d DeltaAction) MarshalJSON() ([]byte, error) {
|
||||
}
|
||||
|
||||
func (d *DeltaAction) UnmarshalJSON(b []byte) error {
|
||||
fmt.Println(string(b))
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
@@ -81,6 +81,10 @@ type Delta struct {
|
||||
source *Client
|
||||
}
|
||||
|
||||
func (d Delta) String() string {
|
||||
return fmt.Sprintf("%s:%q(%v->%v)", d.Action, strings.Join(d.Lines, "\n"), d.Start, d.End)
|
||||
}
|
||||
|
||||
func (d Delta) Equal(other Delta) bool {
|
||||
if d.Start != other.Start {
|
||||
return false
|
||||
@@ -133,15 +137,18 @@ func (d *Document) applyInsert(dl Delta) {
|
||||
|
||||
row := dl.Start.Row
|
||||
col := dl.Start.Column
|
||||
line := d.lines[row]
|
||||
|
||||
if uint(len(d.lines)) == row {
|
||||
d.lines = append(d.lines, "")
|
||||
}
|
||||
|
||||
line := d.line(row)
|
||||
|
||||
if dl.nLines() == 1 {
|
||||
d.lines[row] = line[:col] + dl.line(0) + line[col:]
|
||||
} else {
|
||||
newlines := []string{}
|
||||
if row != 0 {
|
||||
newlines = append(newlines, d.lines[:row-1]...) // old content
|
||||
}
|
||||
newlines = append(newlines, d.lines[:row]...) // old content
|
||||
newlines = append(newlines, d.lines[row][:col]+dl.Lines[0])
|
||||
newlines = append(newlines, dl.Lines[1:]...) // new content
|
||||
newlines[len(newlines)-1] += d.lines[row][col:]
|
||||
@@ -204,7 +211,7 @@ func (d *Document) Apply(dls ...Delta) error {
|
||||
|
||||
func (d *Document) validate(dl Delta) error {
|
||||
if !d.InDocument(dl.Start) {
|
||||
return fmt.Errorf("start is not in document")
|
||||
return fmt.Errorf("start %v is not in document %q", dl.Start, d.contents())
|
||||
}
|
||||
|
||||
if dl.Action == DeltaRemove && !d.InDocument(dl.End) {
|
||||
@@ -217,8 +224,8 @@ func (d *Document) validate(dl Delta) error {
|
||||
|
||||
lastDlLine := dl.line(dl.nRows() - 1)
|
||||
|
||||
if uint(len(lastDlLine)) != dl.cols() {
|
||||
return fmt.Errorf("delta has %d chars on the final line, but positions show range of %d chars", len(lastDlLine), dl.cols())
|
||||
if !(len(lastDlLine) == 0 && dl.cols() < 0) && len(lastDlLine) != int(math.Abs(float64(dl.cols()))) {
|
||||
return fmt.Errorf("delta %v has %d chars on the final line, but positions (%v -> %v) show range of %d chars", dl, len(lastDlLine), dl.Start, dl.End, dl.cols())
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
Reference in New Issue
Block a user