diff --git a/packages/angular_devkit/schematics/src/utility/update-buffer.ts b/packages/angular_devkit/schematics/src/utility/update-buffer.ts index 67ceec7f5be2..e80d724dc3d4 100644 --- a/packages/angular_devkit/schematics/src/utility/update-buffer.ts +++ b/packages/angular_devkit/schematics/src/utility/update-buffer.ts @@ -238,8 +238,15 @@ export class UpdateBuffer extends UpdateBufferBase { } protected _slice(start: number): [Chunk, Chunk] { - // If start is longer than the content, use start, otherwise determine exact position in string. - const index = start >= this._originalContent.length ? start : this._getTextPosition(start); + let index: number; + + if (start >= this._originalContent.length) { + index = start; + } else if (start < 0) { + index = this._originalContent.length + start; + } else { + index = this._getTextPosition(start); + } this._assertIndex(index); @@ -294,8 +301,11 @@ export class UpdateBuffer extends UpdateBufferBase { } remove(index: number, length: number) { - const end = index + length; + if (length === 0) { + return; + } + const end = index + length; const first = this._slice(index)[1]; const last = this._slice(end)[1]; diff --git a/packages/angular_devkit/schematics/src/utility/update-buffer_spec.ts b/packages/angular_devkit/schematics/src/utility/update-buffer_spec.ts index 93d46dde0fc3..c0b120bc363c 100644 --- a/packages/angular_devkit/schematics/src/utility/update-buffer_spec.ts +++ b/packages/angular_devkit/schematics/src/utility/update-buffer_spec.ts @@ -178,6 +178,26 @@ describe('UpdateBuffer', () => { buffer.remove(0, 6); expect(buffer.toString()).toBe('ABC'); }); + + it('is able to insert after a zero-length removal', () => { + const mb = new UpdateBuffer(Buffer.from('123')); + + mb.remove(0, 0); + expect(mb.toString()).toBe('123'); + + mb.insertRight(0, Buffer.from('0')); + expect(mb.toString()).toBe('0123'); + }); + + it('is able to insert after a negative-length removal', () => { + const mb = new UpdateBuffer(Buffer.from('123')); + + mb.remove(0, -1); + expect(mb.toString()).toBe('3'); + + mb.insertRight(0, Buffer.from('0')); + expect(mb.toString()).toBe('03'); + }); }); describe('generate', () => { @@ -355,6 +375,26 @@ describe('UpdateBuffer2', () => { buffer.remove(0, 6); expect(buffer.toString()).toBe('ABCDEF'); }); + + it('is able to insert after a zero-length removal', () => { + const mb = new UpdateBuffer2(Buffer.from('123')); + + mb.remove(0, 0); + expect(mb.toString()).toBe('123'); + + mb.insertRight(0, Buffer.from('0')); + expect(mb.toString()).toBe('0123'); + }); + + it('is able to insert after a negative-length removal', () => { + const mb = new UpdateBuffer2(Buffer.from('123')); + + mb.remove(0, -1); + expect(mb.toString()).toBe('3'); + + mb.insertRight(0, Buffer.from('0')); + expect(mb.toString()).toBe('03'); + }); }); describe('generate', () => {