From 0e8d4143f13e6e0aaaa770a6883271a7d18b4256 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ullrich=20Sch=C3=A4fer?= Date: Fri, 14 Aug 2020 13:54:28 +0200 Subject: [PATCH 1/2] Inlining Op.iterator --- src/Delta.ts | 19 ++++++++++--------- src/Op.ts | 5 ----- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/src/Delta.ts b/src/Delta.ts index 31ef73d..8b99763 100644 --- a/src/Delta.ts +++ b/src/Delta.ts @@ -3,6 +3,7 @@ import cloneDeep from 'lodash.clonedeep'; import isEqual from 'lodash.isequal'; import AttributeMap from './AttributeMap'; import Op from './Op'; +import Iterator from './Iterator'; const NULL_CHARACTER = String.fromCharCode(0); // Placeholder char for embed in diff() @@ -168,7 +169,7 @@ class Delta { slice(start = 0, end = Infinity): Delta { const ops = []; - const iter = Op.iterator(this.ops); + const iter = new Iterator(this.ops); let index = 0; while (index < end && iter.hasNext()) { let nextOp; @@ -184,8 +185,8 @@ class Delta { } compose(other: Delta): Delta { - const thisIter = Op.iterator(this.ops); - const otherIter = Op.iterator(other.ops); + const thisIter = new Iterator(this.ops); + const otherIter = new Iterator(other.ops); const ops = []; const firstOther = otherIter.peek(); if ( @@ -281,8 +282,8 @@ class Delta { }); const retDelta = new Delta(); const diffResult = diff(strings[0], strings[1], cursor); - const thisIter = Op.iterator(this.ops); - const otherIter = Op.iterator(other.ops); + const thisIter = new Iterator(this.ops); + const otherIter = new Iterator(other.ops); diffResult.forEach((component: diff.Diff) => { let length = component[1].length; while (length > 0) { @@ -329,7 +330,7 @@ class Delta { ) => boolean | void, newline = '\n', ): void { - const iter = Op.iterator(this.ops); + const iter = new Iterator(this.ops); let line = new Delta(); let i = 0; while (iter.hasNext()) { @@ -395,8 +396,8 @@ class Delta { return this.transformPosition(arg, priority); } const other: Delta = arg; - const thisIter = Op.iterator(this.ops); - const otherIter = Op.iterator(other.ops); + const thisIter = new Iterator(this.ops); + const otherIter = new Iterator(other.ops); const delta = new Delta(); while (thisIter.hasNext() || otherIter.hasNext()) { if ( @@ -433,7 +434,7 @@ class Delta { transformPosition(index: number, priority = false): number { priority = !!priority; - const thisIter = Op.iterator(this.ops); + const thisIter = new Iterator(this.ops); let offset = 0; while (thisIter.hasNext() && offset <= index) { const length = thisIter.peekLength(); diff --git a/src/Op.ts b/src/Op.ts index 63e8a29..114ccdb 100644 --- a/src/Op.ts +++ b/src/Op.ts @@ -1,5 +1,4 @@ import AttributeMap from './AttributeMap'; -import Iterator from './Iterator'; interface Op { // only one property out of {insert, delete, retain} will be present @@ -11,10 +10,6 @@ interface Op { } namespace Op { - export function iterator(ops: Op[]): Iterator { - return new Iterator(ops); - } - export function length(op: Op): number { if (typeof op.delete === 'number') { return op.delete; From 5358738549302177f8baaf178e3efb4fd4492922 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ullrich=20Sch=C3=A4fer?= Date: Fri, 14 Aug 2020 14:00:21 +0200 Subject: [PATCH 2/2] Extracting iterator tests --- src/Delta.ts | 1 + test/iterator.js | 102 +++++++++++++++++++++++++++++++++++++++++++++++ test/op.js | 100 ---------------------------------------------- 3 files changed, 103 insertions(+), 100 deletions(-) create mode 100644 test/iterator.js diff --git a/src/Delta.ts b/src/Delta.ts index 8b99763..e3c754c 100644 --- a/src/Delta.ts +++ b/src/Delta.ts @@ -9,6 +9,7 @@ const NULL_CHARACTER = String.fromCharCode(0); // Placeholder char for embed in class Delta { static Op = Op; + static Iterator = Iterator; static AttributeMap = AttributeMap; ops: Op[]; diff --git a/test/iterator.js b/test/iterator.js new file mode 100644 index 0000000..f1bd988 --- /dev/null +++ b/test/iterator.js @@ -0,0 +1,102 @@ +var Delta = require('../dist/Delta'); +var Iterator = require('../dist/Delta').Iterator; + +describe('Iterator', function() { + beforeEach(function() { + this.delta = new Delta() + .insert('Hello', { bold: true }) + .retain(3) + .insert(2, { src: 'http://quilljs.com/' }) + .delete(4); + }); + + it('hasNext() true', function() { + var iter = new Iterator(this.delta.ops); + expect(iter.hasNext()).toEqual(true); + }); + + it('hasNext() false', function() { + var iter = new Iterator([]); + expect(iter.hasNext()).toEqual(false); + }); + + it('peekLength() offset === 0', function() { + var iter = new Iterator(this.delta.ops); + expect(iter.peekLength()).toEqual(5); + iter.next(); + expect(iter.peekLength()).toEqual(3); + iter.next(); + expect(iter.peekLength()).toEqual(1); + iter.next(); + expect(iter.peekLength()).toEqual(4); + }); + + it('peekLength() offset > 0', function() { + var iter = new Iterator(this.delta.ops); + iter.next(2); + expect(iter.peekLength()).toEqual(5 - 2); + }); + + it('peekLength() no ops left', function() { + var iter = new Iterator([]); + expect(iter.peekLength()).toEqual(Infinity); + }); + + it('peekType()', function() { + var iter = new Iterator(this.delta.ops); + expect(iter.peekType()).toEqual('insert'); + iter.next(); + expect(iter.peekType()).toEqual('retain'); + iter.next(); + expect(iter.peekType()).toEqual('insert'); + iter.next(); + expect(iter.peekType()).toEqual('delete'); + iter.next(); + expect(iter.peekType()).toEqual('retain'); + }); + + it('next()', function() { + var iter = new Iterator(this.delta.ops); + for (var i = 0; i < this.delta.ops.length; i += 1) { + expect(iter.next()).toEqual(this.delta.ops[i]); + } + expect(iter.next()).toEqual({ retain: Infinity }); + expect(iter.next(4)).toEqual({ retain: Infinity }); + expect(iter.next()).toEqual({ retain: Infinity }); + }); + + it('next(length)', function() { + var iter = new Iterator(this.delta.ops); + expect(iter.next(2)).toEqual({ + insert: 'He', + attributes: { bold: true }, + }); + expect(iter.next(10)).toEqual({ + insert: 'llo', + attributes: { bold: true }, + }); + expect(iter.next(1)).toEqual({ retain: 1 }); + expect(iter.next(2)).toEqual({ retain: 2 }); + }); + + it('rest()', function() { + var iter = new Iterator(this.delta.ops); + iter.next(2); + expect(iter.rest()).toEqual([ + { insert: 'llo', attributes: { bold: true } }, + { retain: 3 }, + { insert: 2, attributes: { src: 'http://quilljs.com/' } }, + { delete: 4 }, + ]); + iter.next(3); + expect(iter.rest()).toEqual([ + { retain: 3 }, + { insert: 2, attributes: { src: 'http://quilljs.com/' } }, + { delete: 4 }, + ]); + iter.next(3); + iter.next(2); + iter.next(4); + expect(iter.rest()).toEqual([]); + }); +}); diff --git a/test/op.js b/test/op.js index 2e104f2..8d9d7b7 100644 --- a/test/op.js +++ b/test/op.js @@ -19,104 +19,4 @@ describe('Op', function() { expect(Op.length({ insert: 2 })).toEqual(1); }); }); - - describe('iterator()', function() { - beforeEach(function() { - this.delta = new Delta() - .insert('Hello', { bold: true }) - .retain(3) - .insert(2, { src: 'http://quilljs.com/' }) - .delete(4); - }); - - it('hasNext() true', function() { - var iter = Op.iterator(this.delta.ops); - expect(iter.hasNext()).toEqual(true); - }); - - it('hasNext() false', function() { - var iter = Op.iterator([]); - expect(iter.hasNext()).toEqual(false); - }); - - it('peekLength() offset === 0', function() { - var iter = Op.iterator(this.delta.ops); - expect(iter.peekLength()).toEqual(5); - iter.next(); - expect(iter.peekLength()).toEqual(3); - iter.next(); - expect(iter.peekLength()).toEqual(1); - iter.next(); - expect(iter.peekLength()).toEqual(4); - }); - - it('peekLength() offset > 0', function() { - var iter = Op.iterator(this.delta.ops); - iter.next(2); - expect(iter.peekLength()).toEqual(5 - 2); - }); - - it('peekLength() no ops left', function() { - var iter = Op.iterator([]); - expect(iter.peekLength()).toEqual(Infinity); - }); - - it('peekType()', function() { - var iter = Op.iterator(this.delta.ops); - expect(iter.peekType()).toEqual('insert'); - iter.next(); - expect(iter.peekType()).toEqual('retain'); - iter.next(); - expect(iter.peekType()).toEqual('insert'); - iter.next(); - expect(iter.peekType()).toEqual('delete'); - iter.next(); - expect(iter.peekType()).toEqual('retain'); - }); - - it('next()', function() { - var iter = Op.iterator(this.delta.ops); - for (var i = 0; i < this.delta.ops.length; i += 1) { - expect(iter.next()).toEqual(this.delta.ops[i]); - } - expect(iter.next()).toEqual({ retain: Infinity }); - expect(iter.next(4)).toEqual({ retain: Infinity }); - expect(iter.next()).toEqual({ retain: Infinity }); - }); - - it('next(length)', function() { - var iter = Op.iterator(this.delta.ops); - expect(iter.next(2)).toEqual({ - insert: 'He', - attributes: { bold: true }, - }); - expect(iter.next(10)).toEqual({ - insert: 'llo', - attributes: { bold: true }, - }); - expect(iter.next(1)).toEqual({ retain: 1 }); - expect(iter.next(2)).toEqual({ retain: 2 }); - }); - - it('rest()', function() { - var iter = Op.iterator(this.delta.ops); - iter.next(2); - expect(iter.rest()).toEqual([ - { insert: 'llo', attributes: { bold: true } }, - { retain: 3 }, - { insert: 2, attributes: { src: 'http://quilljs.com/' } }, - { delete: 4 }, - ]); - iter.next(3); - expect(iter.rest()).toEqual([ - { retain: 3 }, - { insert: 2, attributes: { src: 'http://quilljs.com/' } }, - { delete: 4 }, - ]); - iter.next(3); - iter.next(2); - iter.next(4); - expect(iter.rest()).toEqual([]); - }); - }); });