easy-richtextarea 4.0.3 → 4.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -8
- package/example.js +1399 -982
- package/lib/constants.js +13 -4
- package/lib/contentCompare.js +34 -0
- package/lib/example/richTextarea.js +2 -2
- package/lib/example/view.js +18 -9
- package/lib/keyCodes.js +13 -0
- package/lib/operation/delete.js +101 -52
- package/lib/operation/empty.js +21 -6
- package/lib/operation/insert.js +78 -31
- package/lib/operations/fromJSON.js +4 -4
- package/lib/operations/generate.js +3 -3
- package/lib/operations/transform.js +3 -7
- package/lib/richTextarea.js +244 -156
- package/lib/selection.js +55 -13
- package/lib/types.js +13 -13
- package/lib/undoBuffer.js +105 -0
- package/package.json +3 -2
- package/src/constants.js +1 -0
- package/src/contentCompare.js +34 -0
- package/src/example/richTextarea.js +11 -9
- package/src/example/view.js +28 -10
- package/src/keyCodes.js +3 -0
- package/src/operation/delete.js +135 -58
- package/src/operation/empty.js +19 -14
- package/src/operation/insert.js +97 -39
- package/src/operations/fromJSON.js +4 -4
- package/src/operations/generate.js +8 -4
- package/src/operations/transform.js +3 -3
- package/src/richTextarea.js +316 -185
- package/src/selection.js +53 -9
- package/src/types.js +6 -6
- package/src/undoBuffer.js +73 -0
- package/test/content/transform.js +9 -11
- package/test/helpers.js +27 -21
- package/test/operation/delete.js +187 -147
- package/test/operation/empty.js +3 -5
- package/test/operation/insert.js +134 -118
- package/test/operations/generate.js +19 -22
- package/test/operations/transform.js +37 -98
- package/lib/stringCompare.js +0 -33
- package/src/stringCompare.js +0 -33
package/test/operation/insert.js
CHANGED
|
@@ -4,183 +4,199 @@ const { assert } = require("chai"),
|
|
|
4
4
|
{ arrayUtilities } = require("necessary"),
|
|
5
5
|
{ EmptyOperation, DeleteOperation, InsertOperation } = require("../../lib/main"); ///
|
|
6
6
|
|
|
7
|
-
const helpers = require("../helpers");
|
|
8
|
-
|
|
9
7
|
const { first, second } = arrayUtilities;
|
|
10
8
|
|
|
11
9
|
describe("InsertOperation", () => {
|
|
12
10
|
describe("transform", () => {
|
|
13
|
-
it("
|
|
14
|
-
const insertOperation1 = InsertOperation.
|
|
15
|
-
|
|
16
|
-
transformedOperations = insertOperation1.transformOperation(
|
|
11
|
+
it("leaves an empty operation intact", () => {
|
|
12
|
+
const insertOperation1 = InsertOperation.fromContentAndPosition("nhTY", 1),
|
|
13
|
+
emptyOperation2 = EmptyOperation.fromNothing(),
|
|
14
|
+
transformedOperations = insertOperation1.transformOperation(emptyOperation2);
|
|
17
15
|
|
|
18
16
|
assert.lengthOf(transformedOperations, 1);
|
|
19
17
|
|
|
20
18
|
const firstTransformedOperation = first(transformedOperations),
|
|
21
19
|
transformedOperation = firstTransformedOperation, ///
|
|
22
20
|
transformedOperationJSON = transformedOperation.toJSON(),
|
|
23
|
-
expectedTransformedOperation =
|
|
21
|
+
expectedTransformedOperation = emptyOperation2.clone(),
|
|
24
22
|
expectedTransformedOperationJSON = expectedTransformedOperation.toJSON();
|
|
25
23
|
|
|
26
24
|
assert.deepEqual(transformedOperationJSON, expectedTransformedOperationJSON)
|
|
27
25
|
});
|
|
28
26
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
27
|
+
describe("to the left of another insert", () => {
|
|
28
|
+
it("moves the other insert to the right by its own length", () => {
|
|
29
|
+
const insertOperation1 = InsertOperation.fromContentAndPosition("iUYHgt", 2),
|
|
30
|
+
insertOperation2 = InsertOperation.fromContentAndPosition("ahBGFRtq", 10),
|
|
31
|
+
transformedOperations = insertOperation1.transformOperation(insertOperation2);
|
|
33
32
|
|
|
34
|
-
|
|
33
|
+
assert.lengthOf(transformedOperations, 1);
|
|
35
34
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
35
|
+
const firstTransformedOperation = first(transformedOperations),
|
|
36
|
+
transformedOperation = firstTransformedOperation, ///
|
|
37
|
+
transformedOperationJSON = transformedOperation.toJSON(),
|
|
38
|
+
expectedTransformedOperation = InsertOperation.fromContentAndPosition("ahBGFRtq", 16),
|
|
39
|
+
expectedTransformedOperationJSON = expectedTransformedOperation.toJSON();
|
|
41
40
|
|
|
42
|
-
|
|
41
|
+
assert.deepEqual(transformedOperationJSON, expectedTransformedOperationJSON)
|
|
42
|
+
});
|
|
43
43
|
});
|
|
44
44
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
45
|
+
describe("at the same position whilst lexicographically less than another insert", () => {
|
|
46
|
+
it("moves the other insert to the right by its own length", () => {
|
|
47
|
+
const insertOperation1 = InsertOperation.fromContentAndPosition("acnhJU", 4),
|
|
48
|
+
insertOperation2 = InsertOperation.fromContentAndPosition("xKId", 4),
|
|
49
|
+
transformedOperations = insertOperation1.transformOperation(insertOperation2);
|
|
49
50
|
|
|
50
|
-
|
|
51
|
+
assert.lengthOf(transformedOperations, 1);
|
|
51
52
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
53
|
+
const firstTransformedOperation = first(transformedOperations),
|
|
54
|
+
transformedOperation = firstTransformedOperation, ///
|
|
55
|
+
transformedOperationJSON = transformedOperation.toJSON(),
|
|
56
|
+
expectedTransformedOperation = InsertOperation.fromContentAndPosition("xKId", 10),
|
|
57
|
+
expectedTransformedOperationJSON = expectedTransformedOperation.toJSON();
|
|
57
58
|
|
|
58
|
-
|
|
59
|
+
assert.deepEqual(transformedOperationJSON, expectedTransformedOperationJSON)
|
|
60
|
+
});
|
|
59
61
|
});
|
|
60
62
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
63
|
+
describe("at the same position whilst lexicographically greater than another insert", () => {
|
|
64
|
+
it("leaves the other insert intact", () => {
|
|
65
|
+
const insertOperation1 = InsertOperation.fromContentAndPosition("xcnhJU", 4),
|
|
66
|
+
insertOperation2 = InsertOperation.fromContentAndPosition("aKId", 4),
|
|
67
|
+
transformedOperations = insertOperation1.transformOperation(insertOperation2);
|
|
65
68
|
|
|
66
|
-
|
|
69
|
+
assert.lengthOf(transformedOperations, 1);
|
|
67
70
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
71
|
+
const firstTransformedOperation = first(transformedOperations),
|
|
72
|
+
transformedOperation = firstTransformedOperation, ///
|
|
73
|
+
transformedOperationJSON = transformedOperation.toJSON(),
|
|
74
|
+
expectedTransformedOperation = InsertOperation.fromContentAndPosition("aKId", 4),
|
|
75
|
+
expectedTransformedOperationJSON = expectedTransformedOperation.toJSON();
|
|
73
76
|
|
|
74
|
-
|
|
77
|
+
assert.deepEqual(transformedOperationJSON, expectedTransformedOperationJSON)
|
|
78
|
+
});
|
|
75
79
|
});
|
|
76
80
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
+
describe("at the same position whilst lexicographically equal to another insert", () => {
|
|
82
|
+
it("leaves the other insert intact", () => {
|
|
83
|
+
const insertOperation1 = InsertOperation.fromContentAndPosition("xcnhJU", 4),
|
|
84
|
+
insertOperation2 = InsertOperation.fromContentAndPosition("xcnhJU", 4),
|
|
85
|
+
transformedOperations = insertOperation1.transformOperation(insertOperation2);
|
|
81
86
|
|
|
82
|
-
|
|
87
|
+
assert.lengthOf(transformedOperations, 1);
|
|
83
88
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
+
const firstTransformedOperation = first(transformedOperations),
|
|
90
|
+
transformedOperation = firstTransformedOperation, ///
|
|
91
|
+
transformedOperationJSON = transformedOperation.toJSON(),
|
|
92
|
+
expectedTransformedOperation = InsertOperation.fromContentAndPosition("xcnhJU", 4),
|
|
93
|
+
expectedTransformedOperationJSON = expectedTransformedOperation.toJSON();
|
|
89
94
|
|
|
90
|
-
|
|
95
|
+
assert.deepEqual(transformedOperationJSON, expectedTransformedOperationJSON)
|
|
96
|
+
});
|
|
91
97
|
});
|
|
92
98
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
99
|
+
describe("to the right of another insert", () => {
|
|
100
|
+
it("leaves the other insert intact", () => {
|
|
101
|
+
const insertOperation1 = InsertOperation.fromContentAndPosition("kiuj", 14),
|
|
102
|
+
insertOperation2 = InsertOperation.fromContentAndPosition("xcnhJU", 4),
|
|
103
|
+
transformedOperations = insertOperation1.transformOperation(insertOperation2);
|
|
97
104
|
|
|
98
|
-
|
|
105
|
+
assert.lengthOf(transformedOperations, 1);
|
|
99
106
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
107
|
+
const firstTransformedOperation = first(transformedOperations),
|
|
108
|
+
transformedOperation = firstTransformedOperation, ///
|
|
109
|
+
transformedOperationJSON = transformedOperation.toJSON(),
|
|
110
|
+
expectedTransformedOperation = InsertOperation.fromContentAndPosition("xcnhJU", 4),
|
|
111
|
+
expectedTransformedOperationJSON = expectedTransformedOperation.toJSON();
|
|
105
112
|
|
|
106
|
-
|
|
113
|
+
assert.deepEqual(transformedOperationJSON, expectedTransformedOperationJSON)
|
|
114
|
+
});
|
|
107
115
|
});
|
|
108
116
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
117
|
+
describe("to the left of a delete", () => {
|
|
118
|
+
it("moves the other delete to the right by its own length", () => {
|
|
119
|
+
const insertOperation1 = InsertOperation.fromContentAndPosition("jabgTF", 2),
|
|
120
|
+
deleteOperation2 = DeleteOperation.fromContentAndPosition("cHYg", 10),
|
|
121
|
+
transformedOperations = insertOperation1.transformOperation(deleteOperation2);
|
|
113
122
|
|
|
114
|
-
|
|
123
|
+
assert.lengthOf(transformedOperations, 1);
|
|
115
124
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
125
|
+
const firstTransformedOperation = first(transformedOperations),
|
|
126
|
+
transformedOperation = firstTransformedOperation, ///
|
|
127
|
+
transformedOperationJSON = transformedOperation.toJSON(),
|
|
128
|
+
expectedTransformedOperation = DeleteOperation.fromContentAndPosition("cHYg", 16),
|
|
129
|
+
expectedTransformedOperationJSON = expectedTransformedOperation.toJSON();
|
|
121
130
|
|
|
122
|
-
|
|
131
|
+
assert.deepEqual(transformedOperationJSON, expectedTransformedOperationJSON);
|
|
132
|
+
});
|
|
123
133
|
});
|
|
124
134
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
assert.lengthOf(transformedOperations, 2);
|
|
135
|
+
describe("in the same position as a delete", () => {
|
|
136
|
+
it("moves the other delete to the right by its own length", () => {
|
|
137
|
+
const insertOperation1 = InsertOperation.fromContentAndPosition("jabgTF", 2),
|
|
138
|
+
deleteOperation2 = DeleteOperation.fromContentAndPosition("cHYg", 2),
|
|
139
|
+
transformedOperations = insertOperation1.transformOperation(deleteOperation2);
|
|
131
140
|
|
|
132
|
-
|
|
133
|
-
secondTransformedOperation = second(transformedOperations),
|
|
134
|
-
firstTransformedOperationJSON = firstTransformedOperation.toJSON(),
|
|
135
|
-
secondTransformedOperationJSON = secondTransformedOperation.toJSON(),
|
|
136
|
-
firstExpectedTransformedOperation = DeleteOperation.fromLengthAndPosition(1, 0),
|
|
137
|
-
secondExpectedTransformedOperation = DeleteOperation.fromLengthAndPosition(1, 1),
|
|
138
|
-
firstExpectedTransformedOperationJSON = firstExpectedTransformedOperation.toJSON(),
|
|
139
|
-
secondExpectedTransformedOperationJSON = secondExpectedTransformedOperation.toJSON();
|
|
140
|
-
|
|
141
|
-
assert.deepEqual(firstTransformedOperationJSON, firstExpectedTransformedOperationJSON);
|
|
142
|
-
assert.deepEqual(secondTransformedOperationJSON, secondExpectedTransformedOperationJSON);
|
|
143
|
-
});
|
|
141
|
+
assert.lengthOf(transformedOperations, 1);
|
|
144
142
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
assert.lengthOf(transformedOperations, 1);
|
|
143
|
+
const firstTransformedOperation = first(transformedOperations),
|
|
144
|
+
transformedOperation = firstTransformedOperation, ///
|
|
145
|
+
transformedOperationJSON = transformedOperation.toJSON(),
|
|
146
|
+
expectedTransformedOperation = DeleteOperation.fromContentAndPosition("cHYg", 8),
|
|
147
|
+
expectedTransformedOperationJSON = expectedTransformedOperation.toJSON();
|
|
151
148
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
expectedTransformedOperation = DeleteOperation.fromLengthAndPosition(1, 2),
|
|
156
|
-
expectedTransformedOperationJSON = expectedTransformedOperation.toJSON();
|
|
149
|
+
assert.deepEqual(transformedOperationJSON, expectedTransformedOperationJSON);
|
|
150
|
+
});
|
|
151
|
+
});
|
|
157
152
|
|
|
158
|
-
|
|
153
|
+
describe("strictly overlapped by a delete", () => {
|
|
154
|
+
it("splits the delete in two", () => {
|
|
155
|
+
const insertOperation1 = InsertOperation.fromContentAndPosition("XsAz", 4),
|
|
156
|
+
deleteOperation2 = DeleteOperation.fromContentAndPosition("xhytgGTY", 2),
|
|
157
|
+
transformedOperations = insertOperation1.transformOperation(deleteOperation2);
|
|
158
|
+
|
|
159
|
+
assert.lengthOf(transformedOperations, 2);
|
|
160
|
+
|
|
161
|
+
const firstTransformedOperation = first(transformedOperations),
|
|
162
|
+
secondTransformedOperation = second(transformedOperations),
|
|
163
|
+
firstTransformedOperationJSON = firstTransformedOperation.toJSON(),
|
|
164
|
+
secondTransformedOperationJSON = secondTransformedOperation.toJSON(),
|
|
165
|
+
firstExpectedTransformedOperation = DeleteOperation.fromContentAndPosition("xh", 2),
|
|
166
|
+
firstExpectedTransformedOperationJSON = firstExpectedTransformedOperation.toJSON(),
|
|
167
|
+
secondExpectedTransformedOperation = DeleteOperation.fromContentAndPosition("ytgGTY", 6),
|
|
168
|
+
secondExpectedTransformedOperationJSON = secondExpectedTransformedOperation.toJSON();
|
|
169
|
+
|
|
170
|
+
assert.deepEqual(firstTransformedOperationJSON, firstExpectedTransformedOperationJSON);
|
|
171
|
+
assert.deepEqual(secondTransformedOperationJSON, secondExpectedTransformedOperationJSON);
|
|
172
|
+
});
|
|
159
173
|
});
|
|
160
174
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
175
|
+
describe("to the right of a delete", () => {
|
|
176
|
+
it("leaves the delete intact", () => {
|
|
177
|
+
const insertOperation1 = InsertOperation.fromContentAndPosition("juhY", 10),
|
|
178
|
+
deleteOperation2 = DeleteOperation.fromContentAndPosition("xhyTYa", 2),
|
|
179
|
+
transformedOperations = insertOperation1.transformOperation(deleteOperation2);
|
|
165
180
|
|
|
166
|
-
|
|
181
|
+
assert.lengthOf(transformedOperations, 1);
|
|
167
182
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
183
|
+
const firstTransformedOperation = first(transformedOperations),
|
|
184
|
+
transformedOperation = firstTransformedOperation, ///
|
|
185
|
+
transformedOperationJSON = transformedOperation.toJSON(),
|
|
186
|
+
expectedTransformedOperation = DeleteOperation.fromContentAndPosition("xhyTYa", 2),
|
|
187
|
+
expectedTransformedOperationJSON = expectedTransformedOperation.toJSON();
|
|
173
188
|
|
|
174
|
-
|
|
189
|
+
assert.deepEqual(transformedOperationJSON, expectedTransformedOperationJSON);
|
|
190
|
+
});
|
|
175
191
|
});
|
|
176
192
|
});
|
|
177
193
|
|
|
178
194
|
describe("transformContent", () => {
|
|
179
195
|
it("inserts the requisite characters into the content", () => {
|
|
180
|
-
const content =
|
|
181
|
-
emptyOperation = InsertOperation.
|
|
196
|
+
const content = "adsfxvbc",
|
|
197
|
+
emptyOperation = InsertOperation.fromContentAndPosition("123", 1),
|
|
182
198
|
transformedContent = emptyOperation.transformContent(content),
|
|
183
|
-
expectedContent =
|
|
199
|
+
expectedContent = "a123dsfxvbc";
|
|
184
200
|
|
|
185
201
|
assert.equal(transformedContent, expectedContent);
|
|
186
202
|
});
|
|
@@ -190,7 +206,7 @@ describe("InsertOperation", () => {
|
|
|
190
206
|
it("transforms from and to JSON, leaving the operation unchanged", () => {
|
|
191
207
|
const expectedJSON = {
|
|
192
208
|
"type": "insert",
|
|
193
|
-
"
|
|
209
|
+
"content": "a",
|
|
194
210
|
"position": 1
|
|
195
211
|
},
|
|
196
212
|
json = InsertOperation.fromJSON(expectedJSON).toJSON();
|
|
@@ -2,33 +2,30 @@
|
|
|
2
2
|
|
|
3
3
|
const { assert } = require("chai"),
|
|
4
4
|
{ arrayUtilities } = require("necessary"),
|
|
5
|
-
{
|
|
5
|
+
{ InsertOperation, DeleteOperation, generateOperations } = require("../../lib/main"); ///
|
|
6
6
|
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
const{ first, second } = arrayUtilities,
|
|
10
|
-
{ insertType, deleteType } = types;
|
|
7
|
+
const{ first, second } = arrayUtilities;
|
|
11
8
|
|
|
12
9
|
describe("generateOperations", () => {
|
|
13
10
|
describe("the contents are the same", () => {
|
|
14
11
|
it("generates a zero length array of operations", () => {
|
|
15
|
-
const content =
|
|
12
|
+
const content = "ngYtFRdeaQ",
|
|
16
13
|
operations = generateOperations(content, content);
|
|
17
14
|
|
|
18
15
|
assert.lengthOf(operations, 0);
|
|
19
16
|
});
|
|
20
17
|
});
|
|
21
18
|
|
|
22
|
-
describe("the
|
|
19
|
+
describe("the first content is a subset of the second content", () => {
|
|
23
20
|
it("generates a array of operations containing an insert operation", () => {
|
|
24
|
-
const contentA =
|
|
25
|
-
contentB =
|
|
21
|
+
const contentA = "juhGTre",
|
|
22
|
+
contentB = "juhJHuyGTre",
|
|
26
23
|
operations = generateOperations(contentA, contentB);
|
|
27
24
|
|
|
28
25
|
assert.lengthOf(operations, 1);
|
|
29
26
|
|
|
30
27
|
const firstOperation = first(operations),
|
|
31
|
-
insertOperation = InsertOperation.
|
|
28
|
+
insertOperation = InsertOperation.fromContentAndPosition("JHuy", 3),
|
|
32
29
|
operation = firstOperation, ///
|
|
33
30
|
expectedOperation = insertOperation, ///
|
|
34
31
|
operationJSON = operation.toJSON(),
|
|
@@ -38,16 +35,16 @@ describe("generateOperations", () => {
|
|
|
38
35
|
});
|
|
39
36
|
});
|
|
40
37
|
|
|
41
|
-
describe("the
|
|
38
|
+
describe("the second content is a subset of first content", () => {
|
|
42
39
|
it("generates array of operations containing a delete operation", () => {
|
|
43
|
-
const
|
|
44
|
-
|
|
40
|
+
const contentA = "ayHTgvcregd",
|
|
41
|
+
contentB = "ayHTegd",
|
|
45
42
|
operations = generateOperations(contentA, contentB);
|
|
46
43
|
|
|
47
44
|
assert.lengthOf(operations, 1);
|
|
48
45
|
|
|
49
46
|
const firstOperation = first(operations),
|
|
50
|
-
deleteOperation = DeleteOperation.
|
|
47
|
+
deleteOperation = DeleteOperation.fromContentAndPosition("gvcr", 4),
|
|
51
48
|
operation = firstOperation, ///
|
|
52
49
|
expectedOperation = deleteOperation, ///
|
|
53
50
|
operationJSON = operation.toJSON(),
|
|
@@ -59,8 +56,8 @@ describe("generateOperations", () => {
|
|
|
59
56
|
|
|
60
57
|
describe("the contents are different", () => {
|
|
61
58
|
it("generates array of operations containing one delete operation followed by an insert operation", () => {
|
|
62
|
-
const contentA =
|
|
63
|
-
contentB =
|
|
59
|
+
const contentA = "khbgytrcGFRDwr",
|
|
60
|
+
contentB = "khb12buhGTFRDwr",
|
|
64
61
|
operations = generateOperations(contentA, contentB);
|
|
65
62
|
|
|
66
63
|
assert.lengthOf(operations, 2);
|
|
@@ -69,13 +66,13 @@ describe("generateOperations", () => {
|
|
|
69
66
|
secondOperation = second(operations),
|
|
70
67
|
firstOperationJSON = firstOperation.toJSON(),
|
|
71
68
|
secondOperationJSON = secondOperation.toJSON(),
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
expectedSecondOperationType =
|
|
69
|
+
expectedFirstOperation = DeleteOperation.fromContentAndPosition("gytrcG", 3),
|
|
70
|
+
expectedSecondOperation = InsertOperation.fromContentAndPosition("12buhGT", 3),
|
|
71
|
+
expectedFirstOperationJSON = expectedFirstOperation.toJSON(),
|
|
72
|
+
expectedSecondOperationType = expectedSecondOperation.toJSON();
|
|
76
73
|
|
|
77
|
-
assert.deepEqual(
|
|
78
|
-
assert.deepEqual(
|
|
74
|
+
assert.deepEqual(firstOperationJSON, expectedFirstOperationJSON);
|
|
75
|
+
assert.deepEqual(secondOperationJSON, expectedSecondOperationType);
|
|
79
76
|
});
|
|
80
77
|
});
|
|
81
78
|
});
|
|
@@ -1,126 +1,65 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
const { assert } = require("chai"),
|
|
4
|
-
{ transformContent,
|
|
4
|
+
{ transformContent, transformOperations } = require("../../lib/main"); ///
|
|
5
5
|
|
|
6
6
|
const helpers = require("../helpers");
|
|
7
7
|
|
|
8
8
|
describe("transformOperations", () => {
|
|
9
|
-
describe("for two
|
|
10
|
-
it("The intentions are preserved", () => {
|
|
11
|
-
|
|
12
|
-
secondOperationsJSON = [],
|
|
13
|
-
firstOperations = operationsFromJSON(firstOperationsJSON),
|
|
14
|
-
secondOperations = operationsFromJSON(secondOperationsJSON);
|
|
15
|
-
|
|
16
|
-
assertIntentionsPreserved(firstOperations, secondOperations);
|
|
9
|
+
describe("for two sequences each containing a hundred operations", () => {
|
|
10
|
+
it("The intentions are preserved 1", () => {
|
|
11
|
+
assertIntentionsPreserved();
|
|
17
12
|
});
|
|
18
|
-
});
|
|
19
13
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
const firstOperationsJSON = [{
|
|
23
|
-
"type": "insert",
|
|
24
|
-
"string": "xyz",
|
|
25
|
-
"position": 1
|
|
26
|
-
}],
|
|
27
|
-
secondOperationsJSON = [],
|
|
28
|
-
firstOperations = operationsFromJSON(firstOperationsJSON),
|
|
29
|
-
secondOperations = operationsFromJSON(secondOperationsJSON);
|
|
30
|
-
|
|
31
|
-
assertIntentionsPreserved(firstOperations, secondOperations);
|
|
14
|
+
it("The intentions are preserved 2", () => {
|
|
15
|
+
assertIntentionsPreserved();
|
|
32
16
|
});
|
|
33
|
-
});
|
|
34
17
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
const firstOperationsJSON = [{
|
|
38
|
-
"type": "insert",
|
|
39
|
-
"string": "xyz",
|
|
40
|
-
"position": 1
|
|
41
|
-
}],
|
|
42
|
-
secondOperationsJSON = [{
|
|
43
|
-
"type": "delete",
|
|
44
|
-
"length": 2,
|
|
45
|
-
"position": 1
|
|
46
|
-
}],
|
|
47
|
-
firstOperations = operationsFromJSON(firstOperationsJSON),
|
|
48
|
-
secondOperations = operationsFromJSON(secondOperationsJSON);
|
|
49
|
-
|
|
50
|
-
assertIntentionsPreserved(firstOperations, secondOperations);
|
|
18
|
+
it("The intentions are preserved 3", () => {
|
|
19
|
+
assertIntentionsPreserved();
|
|
51
20
|
});
|
|
52
|
-
});
|
|
53
21
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
const firstOperationsJSON = [{
|
|
57
|
-
"type": "insert",
|
|
58
|
-
"string": "xyz",
|
|
59
|
-
"position": 1,
|
|
60
|
-
}],
|
|
61
|
-
secondOperationsJSON = [{
|
|
62
|
-
"type": "insert",
|
|
63
|
-
"string": "abc",
|
|
64
|
-
"position": 3
|
|
65
|
-
},
|
|
66
|
-
{
|
|
67
|
-
"type": "delete",
|
|
68
|
-
"length": 2,
|
|
69
|
-
"position": 1,
|
|
70
|
-
}],
|
|
71
|
-
firstOperations = operationsFromJSON(firstOperationsJSON),
|
|
72
|
-
secondOperations = operationsFromJSON(secondOperationsJSON);
|
|
73
|
-
|
|
74
|
-
assertIntentionsPreserved(firstOperations, secondOperations);
|
|
22
|
+
it("The intentions are preserved 4", () => {
|
|
23
|
+
assertIntentionsPreserved();
|
|
75
24
|
});
|
|
76
|
-
});
|
|
77
25
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
const firstOperationsJSON = [{
|
|
81
|
-
"type": "delete",
|
|
82
|
-
"length": 6,
|
|
83
|
-
"position": 0
|
|
84
|
-
},
|
|
85
|
-
{
|
|
86
|
-
"type": "insert",
|
|
87
|
-
"string": "JQ",
|
|
88
|
-
"position": 0
|
|
89
|
-
}],
|
|
90
|
-
secondOperationsJSON = [{
|
|
91
|
-
"type": "delete",
|
|
92
|
-
"length": 4,
|
|
93
|
-
"position": 0
|
|
94
|
-
},
|
|
95
|
-
{
|
|
96
|
-
"type": "insert",
|
|
97
|
-
"string": "bkW",
|
|
98
|
-
"position": 0
|
|
99
|
-
}],
|
|
100
|
-
firstOperations = operationsFromJSON(firstOperationsJSON),
|
|
101
|
-
secondOperations = operationsFromJSON(secondOperationsJSON);
|
|
102
|
-
|
|
103
|
-
assertIntentionsPreserved(firstOperations, secondOperations);
|
|
26
|
+
it("The intentions are preserved 6", () => {
|
|
27
|
+
assertIntentionsPreserved();
|
|
104
28
|
});
|
|
105
|
-
});
|
|
106
29
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
firstOperations = helpers.operations(content, 100),
|
|
111
|
-
secondOperations = helpers.operations(content, 100);
|
|
30
|
+
it("The intentions are preserved 6", () => {
|
|
31
|
+
assertIntentionsPreserved();
|
|
32
|
+
});
|
|
112
33
|
|
|
113
|
-
|
|
34
|
+
it("The intentions are preserved 7", () => {
|
|
35
|
+
assertIntentionsPreserved();
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it("The intentions are preserved 8", () => {
|
|
39
|
+
assertIntentionsPreserved();
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it("The intentions are preserved 9", () => {
|
|
43
|
+
assertIntentionsPreserved();
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it("The intentions are preserved 10", () => {
|
|
47
|
+
assertIntentionsPreserved();
|
|
114
48
|
});
|
|
115
49
|
});
|
|
116
50
|
});
|
|
117
51
|
|
|
118
|
-
function assertIntentionsPreserved(
|
|
119
|
-
const content = helpers.content(
|
|
120
|
-
|
|
52
|
+
function assertIntentionsPreserved() {
|
|
53
|
+
const content = helpers.content(1000);
|
|
54
|
+
|
|
55
|
+
let firstOperations = helpers.operations(content, 100),
|
|
56
|
+
secondOperations = helpers.operations(content, 100);
|
|
57
|
+
|
|
58
|
+
const transformedFirstOperations = transformOperations(firstOperations, secondOperations),
|
|
121
59
|
transformedSecondOperations = transformOperations(secondOperations, firstOperations);
|
|
122
60
|
|
|
123
61
|
firstOperations = firstOperations.concat(transformedSecondOperations);
|
|
62
|
+
|
|
124
63
|
secondOperations = secondOperations.concat(transformedFirstOperations);
|
|
125
64
|
|
|
126
65
|
const firstTransformedContent = transformContent(content, firstOperations),
|
package/lib/stringCompare.js
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", {
|
|
3
|
-
value: true
|
|
4
|
-
});
|
|
5
|
-
Object.defineProperty(exports, "default", {
|
|
6
|
-
enumerable: true,
|
|
7
|
-
get: function() {
|
|
8
|
-
return stringCompare;
|
|
9
|
-
}
|
|
10
|
-
});
|
|
11
|
-
var _constants = require("./constants");
|
|
12
|
-
function stringCompare(stringA, stringB) {
|
|
13
|
-
if (stringA === _constants.EMPTY_STRING && stringB === _constants.EMPTY_STRING) {
|
|
14
|
-
return false;
|
|
15
|
-
}
|
|
16
|
-
if (stringA === _constants.EMPTY_STRING) {
|
|
17
|
-
return true;
|
|
18
|
-
}
|
|
19
|
-
if (stringB === _constants.EMPTY_STRING) {
|
|
20
|
-
return false;
|
|
21
|
-
}
|
|
22
|
-
var codePointA = stringA.codePointAt(0), codePointB = stringB.codePointAt(0);
|
|
23
|
-
if (codePointA < codePointB) {
|
|
24
|
-
return true;
|
|
25
|
-
}
|
|
26
|
-
if (codePointA > codePointB) {
|
|
27
|
-
return false;
|
|
28
|
-
}
|
|
29
|
-
var subStringA = stringA.substring(1), subStringB = stringB.substring(1);
|
|
30
|
-
return stringCompare(subStringA, subStringB);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9zdHJpbmdDb21wYXJlLmpzIl0sInNvdXJjZXNDb250ZW50IjpbIlwidXNlIHN0cmljdFwiO1xuXG5pbXBvcnQgeyBFTVBUWV9TVFJJTkcgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gc3RyaW5nQ29tcGFyZShzdHJpbmdBLCBzdHJpbmdCKSB7XG4gIGlmICgoc3RyaW5nQSA9PT0gRU1QVFlfU1RSSU5HKSAmJiAoc3RyaW5nQiA9PT0gRU1QVFlfU1RSSU5HKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGlmIChzdHJpbmdBID09PSBFTVBUWV9TVFJJTkcpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGlmIChzdHJpbmdCID09PSBFTVBUWV9TVFJJTkcpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBjb25zdCBjb2RlUG9pbnRBID0gc3RyaW5nQS5jb2RlUG9pbnRBdCgwKSxcbiAgICAgICAgY29kZVBvaW50QiA9IHN0cmluZ0IuY29kZVBvaW50QXQoMCk7XG5cbiAgaWYgKGNvZGVQb2ludEEgPCBjb2RlUG9pbnRCKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBpZiAoY29kZVBvaW50QSA+IGNvZGVQb2ludEIpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBjb25zdCBzdWJTdHJpbmdBID0gc3RyaW5nQS5zdWJzdHJpbmcoMSksXG4gICAgICAgIHN1YlN0cmluZ0IgPSBzdHJpbmdCLnN1YnN0cmluZygxKTtcblxuICByZXR1cm4gc3RyaW5nQ29tcGFyZShzdWJTdHJpbmdBLCBzdWJTdHJpbmdCKTtcbn1cbiJdLCJuYW1lcyI6WyJzdHJpbmdDb21wYXJlIiwic3RyaW5nQSIsInN0cmluZ0IiLCJFTVBUWV9TVFJJTkciLCJjb2RlUG9pbnRBIiwiY29kZVBvaW50QXQiLCJjb2RlUG9pbnRCIiwic3ViU3RyaW5nQSIsInN1YnN0cmluZyIsInN1YlN0cmluZ0IiXSwibWFwcGluZ3MiOiJBQUFBOzs7OytCQUlBOzs7ZUFBd0JBOzs7eUJBRks7QUFFZCxTQUFTQSxjQUFjQyxPQUFPLEVBQUVDLE9BQU8sRUFBRTtJQUN0RCxJQUFJLEFBQUNELFlBQVlFLHVCQUFZLElBQU1ELFlBQVlDLHVCQUFZLEVBQUc7UUFDNUQsT0FBTyxLQUFLO0lBQ2QsQ0FBQztJQUVELElBQUlGLFlBQVlFLHVCQUFZLEVBQUU7UUFDNUIsT0FBTyxJQUFJO0lBQ2IsQ0FBQztJQUVELElBQUlELFlBQVlDLHVCQUFZLEVBQUU7UUFDNUIsT0FBTyxLQUFLO0lBQ2QsQ0FBQztJQUVELElBQU1DLGFBQWFILFFBQVFJLFdBQVcsQ0FBQyxJQUNqQ0MsYUFBYUosUUFBUUcsV0FBVyxDQUFDO0lBRXZDLElBQUlELGFBQWFFLFlBQVk7UUFDM0IsT0FBTyxJQUFJO0lBQ2IsQ0FBQztJQUVELElBQUlGLGFBQWFFLFlBQVk7UUFDM0IsT0FBTyxLQUFLO0lBQ2QsQ0FBQztJQUVELElBQU1DLGFBQWFOLFFBQVFPLFNBQVMsQ0FBQyxJQUMvQkMsYUFBYVAsUUFBUU0sU0FBUyxDQUFDO0lBRXJDLE9BQU9SLGNBQWNPLFlBQVlFO0FBQ25DIn0=
|