Skip to content

Commit

Permalink
fix(docs): the apply result should be consistent (#3806)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jocs authored Oct 22, 2024
1 parent 8a27b31 commit d0054f3
Show file tree
Hide file tree
Showing 19 changed files with 608 additions and 119 deletions.
8 changes: 4 additions & 4 deletions packages/core/src/docs/data-model/json-x/json-x.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@
*/

import type { Doc, JSONOp, Path } from 'ot-json1';
import * as json1 from 'ot-json1';
import type { Nullable } from '../../../shared';
import type { IDocumentBody, IDocumentData } from '../../../types/interfaces';
import type { TextXAction } from '../text-x/action-types';
import type { TPriority } from '../text-x/text-x';
import * as json1 from 'ot-json1';
import { TextX } from '../text-x/text-x';
import type { TextXAction } from '../text-x/action-types';
import type { Nullable } from '../../../shared';

export interface ISubType {
name: string;
Expand All @@ -37,7 +37,7 @@ export interface ISubType {
[k: string]: any;
};

export { JSONOp as JSONXActions, Path as JSONXPath, json1 as JSON1 };
export { json1 as JSON1, JSONOp as JSONXActions, Path as JSONXPath };

export class JSONX {
// static name = 'json-x';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
*/

import { describe, expect, it } from 'vitest';
import { BooleanNumber } from '../../../../types/enum/text-style';
import { ActionIterator } from '../action-iterator';
import { TextXActionType } from '../action-types';
import { BooleanNumber } from '../../../../types/enum/text-style';

describe('Test action iterator', () => {
it('test action iterator basic use', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@
* limitations under the License.
*/

import type { Nullable } from 'vitest';
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
import type { Nullable } from '../../../../shared';

import type { IDocumentBody, ITextRun } from '../../../../types/interfaces';
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
import { UpdateDocsAttributeType } from '../../../../shared';
import { BooleanNumber } from '../../../../types/enum';
import type { IDocumentBody, ITextRun } from '../../../../types/interfaces';
import { deleteParagraphs, deleteTextRuns, insertTextRuns } from '../apply-utils/common';
import { coverTextRuns } from '../apply-utils/update-apply';

Expand Down Expand Up @@ -523,10 +523,12 @@ describe('test case in apply utils', () => {
10
);

expect(body?.textRuns!.length).toBe(3);
expect(body?.textRuns!.length).toBe(4);
expect(body?.textRuns![0].ts?.bl).toBe(BooleanNumber.FALSE);
expect(body?.textRuns![1].ts?.bl).toBe(BooleanNumber.FALSE);
expect(body?.textRuns![2].ts?.bl).toBe(BooleanNumber.FALSE);
expect(body?.textRuns![2].ts?.it).toBe(BooleanNumber.TRUE);
expect(body?.textRuns![3].ts?.bl).toBe(BooleanNumber.FALSE);
});

it('If textRuns doesn\'t intersect, they shouldn\'t be merged', async () => {
Expand Down
253 changes: 253 additions & 0 deletions packages/core/src/docs/data-model/text-x/__tests__/apply.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,253 @@
/**
* Copyright 2023-present DreamNum Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import type { IDocumentBody } from '../../../../types/interfaces';
import type { TextXAction } from '../action-types';
import { describe, expect, it } from 'vitest';
import { BooleanNumber } from '../../../../types/enum';
import { TextXActionType } from '../action-types';
import { TextX } from '../text-x';

function getDefaultDoc() {
const doc: IDocumentBody = {
dataStream: 'w\r\n',
textRuns: [
{
st: 0,
ed: 1,
ts: {
bl: BooleanNumber.TRUE,
},
},
],
};

return doc;
}

function getDefaultDocWithLength2() {
const doc: IDocumentBody = {
dataStream: 'ww\r\n',
textRuns: [
{
st: 0,
ed: 2,
ts: {
bl: BooleanNumber.TRUE,
},
},
],
};

return doc;
}

describe('apply method', () => {
it('should get the same result when apply two actions by order OR composed first case 1', () => {
const actionsA: TextXAction[] = [
{
t: TextXActionType.INSERT,
len: 1,
line: 0,
body: {
dataStream: 'h',
},
},
];
const actionsB: TextXAction[] = [
{
t: TextXActionType.RETAIN,
len: 1,
body: {
dataStream: '',
textRuns: [
{
st: 0,
ed: 1,
ts: {
bl: BooleanNumber.FALSE,
},
},
],
},
segmentId: '',
},
];

const doc1 = getDefaultDoc();
const doc2 = getDefaultDoc();
const doc3 = getDefaultDoc();
const doc4 = getDefaultDoc();

const resultA = TextX.apply(TextX.apply(doc1, actionsA), TextX.transform(actionsB, actionsA, 'left'));
const resultB = TextX.apply(TextX.apply(doc2, actionsB), TextX.transform(actionsA, actionsB, 'right'));

const composedAction1 = TextX.compose(actionsA, TextX.transform(actionsB, actionsA, 'left'));
const composedAction2 = TextX.compose(actionsB, TextX.transform(actionsA, actionsB, 'right'));

const resultC = TextX.apply(doc3, composedAction1);
const resultD = TextX.apply(doc4, composedAction2);

expect(resultA).toEqual(resultB);
expect(resultC).toEqual(resultD);
expect(resultA).toEqual(resultC);
expect(composedAction1).toEqual(composedAction2);
});

// https://github.com/dream-num/univer-pro/issues/2943
it('should get the same result when apply two actions by order OR composed first case 2', () => {
const actionsA: TextXAction[] = [
{
t: TextXActionType.RETAIN,
segmentId: '',
len: 1,
},
{
t: TextXActionType.INSERT,
len: 1,
line: 0,
body: {
dataStream: 'h',
textRuns: [
{
st: 0,
ed: 1,
ts: {
bl: BooleanNumber.TRUE,
},
},
],
},
},
];
const actionsB: TextXAction[] = [
{
t: TextXActionType.RETAIN,
len: 1,
body: {
dataStream: '',
textRuns: [
{
st: 0,
ed: 1,
ts: {
bl: BooleanNumber.FALSE,
},
},
],
},
segmentId: '',
},
];

const doc1 = getDefaultDoc();
const doc2 = getDefaultDoc();
const doc3 = getDefaultDoc();
const doc4 = getDefaultDoc();

const resultA = TextX.apply(TextX.apply(doc1, actionsA), TextX.transform(actionsB, actionsA, 'left'));
const resultB = TextX.apply(TextX.apply(doc2, actionsB), TextX.transform(actionsA, actionsB, 'right'));

const composedAction1 = TextX.compose(actionsA, TextX.transform(actionsB, actionsA, 'left'));
const composedAction2 = TextX.compose(actionsB, TextX.transform(actionsA, actionsB, 'right'));

const resultC = TextX.apply(doc3, composedAction1);
const resultD = TextX.apply(doc4, composedAction2);

// console.log(JSON.stringify(resultA, null, 2));
// console.log(JSON.stringify(resultB, null, 2));

// console.log(JSON.stringify(composedAction2, null, 2));
// console.log(JSON.stringify(resultC, null, 2));

expect(resultA).toEqual(resultB);
expect(resultC).toEqual(resultD);
expect(resultA).toEqual(resultC);
expect(composedAction1).toEqual(composedAction2);
});

it('should get the same result when apply two actions by order OR composed first case 3', () => {
const actionsA: TextXAction[] = [
{
t: TextXActionType.RETAIN,
segmentId: '',
len: 1,
},
{
t: TextXActionType.INSERT,
len: 1,
line: 0,
body: {
dataStream: 'h',
textRuns: [
{
st: 0,
ed: 1,
ts: {
bl: BooleanNumber.TRUE,
},
},
],
},
},
];
const actionsB: TextXAction[] = [
{
t: TextXActionType.RETAIN,
len: 2,
body: {
dataStream: '',
textRuns: [
{
st: 0,
ed: 2,
ts: {
bl: BooleanNumber.FALSE,
},
},
],
},
segmentId: '',
},
];

const doc1 = getDefaultDocWithLength2();
const doc2 = getDefaultDocWithLength2();
const doc3 = getDefaultDocWithLength2();
const doc4 = getDefaultDocWithLength2();

const resultA = TextX.apply(TextX.apply(doc1, actionsA), TextX.transform(actionsB, actionsA, 'left'));
const resultB = TextX.apply(TextX.apply(doc2, actionsB), TextX.transform(actionsA, actionsB, 'right'));

const composedAction1 = TextX.compose(actionsA, TextX.transform(actionsB, actionsA, 'left'));
const composedAction2 = TextX.compose(actionsB, TextX.transform(actionsA, actionsB, 'right'));

const resultC = TextX.apply(doc3, composedAction1);
const resultD = TextX.apply(doc4, composedAction2);

// console.log(JSON.stringify(resultA, null, 2));
// console.log(JSON.stringify(resultB, null, 2));

// console.log('composedAction1', JSON.stringify(composedAction1, null, 2));

// console.log(JSON.stringify(resultC, null, 2));

expect(resultA).toEqual(resultB);
expect(resultC).toEqual(resultD);
expect(resultA).toEqual(resultC);
expect(composedAction1).toEqual(composedAction2);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@
* limitations under the License.
*/

import { describe, expect, it } from 'vitest';
import type { TextXAction } from '../action-types';
import { TextXActionType } from '../action-types';
import { describe, expect, it } from 'vitest';
import { BooleanNumber } from '../../../../types/enum/text-style';
import { TextXActionType } from '../action-types';
import { TextX } from '../text-x';

describe('compose test cases', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@
* limitations under the License.
*/

import { describe, expect, it } from 'vitest';
import type { IDocumentBody } from '../../../../types/interfaces';
import { BooleanNumber } from '../../../../types/enum';
import { TextX } from '../text-x';
import type { TextXAction } from '../action-types';
import { TextXActionType } from '../action-types';
import { describe, expect, it } from 'vitest';
import { UpdateDocsAttributeType } from '../../../../shared/command-enum';
import { BooleanNumber } from '../../../../types/enum';
import { TextXActionType } from '../action-types';
import { TextX } from '../text-x';

describe('test TextX static methods invert and makeInvertible', () => {
it('test TextX static method invert', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@
* limitations under the License.
*/

import { describe, expect, it } from 'vitest';
import { TextX } from '../text-x';
import type { IDocumentBody } from '../../../../types/interfaces/i-document-data';
import { BooleanNumber } from '../../../../types/enum/text-style';
import { describe, expect, it } from 'vitest';
import { UpdateDocsAttributeType } from '../../../../shared/command-enum';
import { BooleanNumber } from '../../../../types/enum/text-style';
import { TextXActionType } from '../action-types';
import { TextX } from '../text-x';

describe('test TextX methods and branches', () => {
describe('test TextX methods', () => {
Expand Down
Loading

0 comments on commit d0054f3

Please sign in to comment.