/**
 * @fileoverview Tests for writer.js.
 */
goog.module('protobuf.binary.WriterTest');

goog.setTestOnly();

// Note to the reader:
// Since the writer behavior changes with the checking level some of the tests
// in this file have to know which checking level is enable to make correct
// assertions.
const BufferDecoder = goog.require('protobuf.binary.BufferDecoder');
const ByteString = goog.require('protobuf.ByteString');
const WireType = goog.require('protobuf.binary.WireType');
const Writer = goog.require('protobuf.binary.Writer');
const {CHECK_BOUNDS, CHECK_TYPE, MAX_FIELD_NUMBER} = goog.require('protobuf.internal.checks');
const {arrayBufferSlice} = goog.require('protobuf.binary.typedArrays');
const {getDoublePairs} = goog.require('protobuf.binary.doubleTestPairs');
const {getFixed32Pairs} = goog.require('protobuf.binary.fixed32TestPairs');
const {getFloatPairs} = goog.require('protobuf.binary.floatTestPairs');
const {getInt32Pairs} = goog.require('protobuf.binary.int32TestPairs');
const {getInt64Pairs} = goog.require('protobuf.binary.int64TestPairs');
const {getPackedBoolPairs} = goog.require('protobuf.binary.packedBoolTestPairs');
const {getPackedDoublePairs} = goog.require('protobuf.binary.packedDoubleTestPairs');
const {getPackedFixed32Pairs} = goog.require('protobuf.binary.packedFixed32TestPairs');
const {getPackedFloatPairs} = goog.require('protobuf.binary.packedFloatTestPairs');
const {getPackedInt32Pairs} = goog.require('protobuf.binary.packedInt32TestPairs');
const {getPackedInt64Pairs} = goog.require('protobuf.binary.packedInt64TestPairs');
const {getPackedSfixed32Pairs} = goog.require('protobuf.binary.packedSfixed32TestPairs');
const {getPackedSfixed64Pairs} = goog.require('protobuf.binary.packedSfixed64TestPairs');
const {getPackedSint32Pairs} = goog.require('protobuf.binary.packedSint32TestPairs');
const {getPackedSint64Pairs} = goog.require('protobuf.binary.packedSint64TestPairs');
const {getPackedUint32Pairs} = goog.require('protobuf.binary.packedUint32TestPairs');
const {getSfixed32Pairs} = goog.require('protobuf.binary.sfixed32TestPairs');
const {getSfixed64Pairs} = goog.require('protobuf.binary.sfixed64TestPairs');
const {getSint32Pairs} = goog.require('protobuf.binary.sint32TestPairs');
const {getSint64Pairs} = goog.require('protobuf.binary.sint64TestPairs');
const {getUint32Pairs} = goog.require('protobuf.binary.uint32TestPairs');


/**
 * @param {...number} bytes
 * @return {!ArrayBuffer}
 */
function createArrayBuffer(...bytes) {
  return new Uint8Array(bytes).buffer;
}

/******************************************************************************
 *                        OPTIONAL FUNCTIONS
 ******************************************************************************/

describe('Writer does', () => {
  it('return an empty ArrayBuffer when nothing is encoded', () => {
    const writer = new Writer();
    expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer());
  });

  it('encode tag', () => {
    const writer = new Writer();
    writer.writeTag(1, WireType.VARINT);
    expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer(0x08));

    writer.writeTag(0x0FFFFFFF, WireType.VARINT);
    expect(writer.getAndResetResultBuffer())
        .toEqual(createArrayBuffer(0xF8, 0xFF, 0xFF, 0xFF, 0x7));

    writer.writeTag(0x10000000, WireType.VARINT);
    expect(writer.getAndResetResultBuffer())
        .toEqual(createArrayBuffer(0x80, 0x80, 0x80, 0x80, 0x08));

    writer.writeTag(0x1FFFFFFF, WireType.VARINT);
    expect(writer.getAndResetResultBuffer())
        .toEqual(createArrayBuffer(0xF8, 0xFF, 0xFF, 0xFF, 0x0F));
  });

  it('reset after calling getAndResetResultBuffer', () => {
    const writer = new Writer();
    writer.writeTag(1, WireType.VARINT);
    writer.getAndResetResultBuffer();
    expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer());
  });

  it('fail when field number is too large for writeTag', () => {
    const writer = new Writer();
    if (CHECK_TYPE) {
      expect(() => writer.writeTag(MAX_FIELD_NUMBER + 1, WireType.VARINT))
          .toThrowError('Field number is out of range: 536870912');
    } else {
      // Note in unchecked mode we produce invalid output for invalid inputs.
      // This test just documents our behavior in those cases.
      // These values might change at any point and are not considered
      // what the implementation should be doing here.
      writer.writeTag(MAX_FIELD_NUMBER + 1, WireType.VARINT);
      expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer(0));
    }
  });

  it('fail when field number is negative for writeTag', () => {
    const writer = new Writer();
    if (CHECK_TYPE) {
      expect(() => writer.writeTag(-1, WireType.VARINT))
          .toThrowError('Field number is out of range: -1');
    } else {
      // Note in unchecked mode we produce invalid output for invalid inputs.
      // This test just documents our behavior in those cases.
      // These values might change at any point and are not considered
      // what the implementation should be doing here.
      writer.writeTag(-1, WireType.VARINT);
      expect(writer.getAndResetResultBuffer())
          .toEqual(createArrayBuffer(0xF8, 0xFF, 0xFF, 0xFF, 0xF));
    }
  });

  it('fail when wire type is invalid for writeTag', () => {
    const writer = new Writer();
    if (CHECK_TYPE) {
      expect(() => writer.writeTag(1, /** @type {!WireType} */ (0x08)))
          .toThrowError('Invalid wire type: 8');
    } else {
      // Note in unchecked mode we produce invalid output for invalid inputs.
      // This test just documents our behavior in those cases.
      // These values might change at any point and are not considered
      // what the implementation should be doing here.
      writer.writeTag(1, /** @type {!WireType} */ (0x08));
      expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer(0x08));
    }
  });

  it('encode singular boolean value', () => {
    const writer = new Writer();
    writer.writeBool(1, true);
    expect(writer.getAndResetResultBuffer())
        .toEqual(createArrayBuffer(0x08, 0x01));
  });

  it('encode length delimited', () => {
    const writer = new Writer();
    writer.writeDelimited(1, createArrayBuffer(0x01, 0x02));
    expect(writer.getAndResetResultBuffer())
        .toEqual(createArrayBuffer(0x0A, 0x02, 0x01, 0x02));
  });
});

describe('Writer.writeBufferDecoder does', () => {
  it('encode BufferDecoder containing a varint value', () => {
    const writer = new Writer();
    const expected = createArrayBuffer(
        0x08, /* varint start= */ 0xFF, /* varint end= */ 0x01, 0x08, 0x01);
    writer.writeBufferDecoder(
        BufferDecoder.fromArrayBuffer(expected), 1, WireType.VARINT, 1);
    const result = writer.getAndResetResultBuffer();
    expect(result).toEqual(arrayBufferSlice(expected, 1, 3));
  });

  it('encode BufferDecoder containing a fixed64 value', () => {
    const writer = new Writer();
    const expected = createArrayBuffer(
        0x09, /* fixed64 start= */ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
        /* fixed64 end= */ 0x08, 0x08, 0x01);
    writer.writeBufferDecoder(
        BufferDecoder.fromArrayBuffer(expected), 1, WireType.FIXED64, 1);
    const result = writer.getAndResetResultBuffer();
    expect(result).toEqual(arrayBufferSlice(expected, 1, 9));
  });

  it('encode BufferDecoder containing a length delimited value', () => {
    const writer = new Writer();
    const expected = createArrayBuffer(
        0xA, /* length= */ 0x03, /* data start= */ 0x01, 0x02,
        /* data end= */ 0x03, 0x08, 0x01);
    writer.writeBufferDecoder(
        BufferDecoder.fromArrayBuffer(expected), 1, WireType.DELIMITED, 1);
    const result = writer.getAndResetResultBuffer();
    expect(result).toEqual(arrayBufferSlice(expected, 1, 5));
  });

  it('encode BufferDecoder containing a group', () => {
    const writer = new Writer();
    const expected = createArrayBuffer(
        0xB, /* group start= */ 0x08, 0x01, /* nested group start= */ 0x0B,
        /* nested group end= */ 0x0C, /* group end= */ 0x0C, 0x08, 0x01);
    writer.writeBufferDecoder(
        BufferDecoder.fromArrayBuffer(expected), 1, WireType.START_GROUP, 1);
    const result = writer.getAndResetResultBuffer();
    expect(result).toEqual(arrayBufferSlice(expected, 1, 6));
  });

  it('encode BufferDecoder containing a fixed32 value', () => {
    const writer = new Writer();
    const expected = createArrayBuffer(
        0x09, /* fixed64 start= */ 0x01, 0x02, 0x03, /* fixed64 end= */ 0x04,
        0x08, 0x01);
    writer.writeBufferDecoder(
        BufferDecoder.fromArrayBuffer(expected), 1, WireType.FIXED32, 1);
    const result = writer.getAndResetResultBuffer();
    expect(result).toEqual(arrayBufferSlice(expected, 1, 5));
  });

  it('fail when encoding out of bound data', () => {
    const writer = new Writer();
    const buffer = createArrayBuffer(0x4, 0x0, 0x1, 0x2, 0x3);
    const subBuffer = arrayBufferSlice(buffer, 0, 2);
    expect(
        () => writer.writeBufferDecoder(
            BufferDecoder.fromArrayBuffer(subBuffer), 0, WireType.DELIMITED, 1))
        .toThrow();
  });
});

describe('Writer.writeBytes does', () => {
  let writer;
  beforeEach(() => {
    writer = new Writer();
  });

  it('encodes empty ByteString', () => {
    writer.writeBytes(1, ByteString.EMPTY);
    const buffer = writer.getAndResetResultBuffer();
    expect(buffer.byteLength).toBe(2);
  });

  it('encodes empty array', () => {
    writer.writeBytes(1, ByteString.fromArrayBuffer(new ArrayBuffer(0)));
    expect(writer.getAndResetResultBuffer())
        .toEqual(createArrayBuffer(
            1 << 3 | 0x02,  // tag (fieldnumber << 3 | (length delimited))
            0,              // length of the bytes
            ));
  });

  it('encodes ByteString', () => {
    const array = createArrayBuffer(1, 2, 3);
    writer.writeBytes(1, ByteString.fromArrayBuffer(array));
    expect(writer.getAndResetResultBuffer())
        .toEqual(createArrayBuffer(
            1 << 3 | 0x02,  // tag (fieldnumber << 3 | (length delimited))
            3,              // length of the bytes
            1,
            2,
            3,
            ));
  });
});

describe('Writer.writeDouble does', () => {
  let writer;
  beforeEach(() => {
    writer = new Writer();
  });

  for (const pair of getDoublePairs()) {
    it(`encode ${pair.name}`, () => {
        writer.writeDouble(1, pair.doubleValue);
        const buffer = new Uint8Array(writer.getAndResetResultBuffer());
        expect(buffer.length).toBe(9);
        // ensure we have a correct tag
        expect(buffer[0]).toEqual(0x09);
        // Encoded values are stored right after the tag
        expect(buffer.subarray(1, 9))
            .toEqual(pair.bufferDecoder.asUint8Array());
    });
  }

  /**
   * NaN may have different value in different browsers. Thus, we need to make
   * the test lenient.
   */
  it('encode NaN', () => {
    writer.writeDouble(1, NaN);
    const buffer = new Uint8Array(writer.getAndResetResultBuffer());
    expect(buffer.length).toBe(9);
    // ensure we have a correct tag
    expect(buffer[0]).toEqual(0x09);
    // Encoded values are stored right after the tag
    const float64 = new DataView(buffer.buffer);
    expect(float64.getFloat64(1, true)).toBeNaN();
  });
});

describe('Writer.writeFixed32 does', () => {
  let writer;
  beforeEach(() => {
    writer = new Writer();
  });

  for (const pair of getFixed32Pairs()) {
    it(`encode ${pair.name}`, () => {
      writer.writeFixed32(1, pair.intValue);
      const buffer = new Uint8Array(writer.getAndResetResultBuffer());
      expect(buffer.length).toBe(5);
      // ensure we have a correct tag
      expect(buffer[0]).toEqual(0x0D);
      // Encoded values are stored right after the tag
      expect(buffer.subarray(1, 5)).toEqual(pair.bufferDecoder.asUint8Array());
    });
  }
});

describe('Writer.writeFloat does', () => {
  let writer;
  beforeEach(() => {
    writer = new Writer();
  });

  for (const pair of getFloatPairs()) {
    it(`encode ${pair.name}`, () => {
      writer.writeFloat(1, pair.floatValue);
      const buffer = new Uint8Array(writer.getAndResetResultBuffer());
      expect(buffer.length).toBe(5);
      // ensure we have a correct tag
      expect(buffer[0]).toEqual(0x0D);
      // Encoded values are stored right after the tag
      expect(buffer.subarray(1, 5)).toEqual(pair.bufferDecoder.asUint8Array());
    });
  }

  /**
   * NaN may have different value in different browsers. Thus, we need to make
   * the test lenient.
   */
  it('encode NaN', () => {
    writer.writeFloat(1, NaN);
    const buffer = new Uint8Array(writer.getAndResetResultBuffer());
    expect(buffer.length).toBe(5);
    // ensure we have a correct tag
    expect(buffer[0]).toEqual(0x0D);
    // Encoded values are stored right after the tag
    const float32 = new DataView(buffer.buffer);
    expect(float32.getFloat32(1, true)).toBeNaN();
  });
});

describe('Writer.writeInt32 does', () => {
  let writer;
  beforeEach(() => {
    writer = new Writer();
  });

  for (const pair of getInt32Pairs()) {
    if (!pair.skip_writer) {
      it(`encode ${pair.name}`, () => {
        writer.writeInt32(1, pair.intValue);
        const buffer = new Uint8Array(writer.getAndResetResultBuffer());
        // ensure we have a correct tag
        expect(buffer[0]).toEqual(0x08);
        // Encoded values are stored right after the tag
        expect(buffer.subarray(1, buffer.length))
            .toEqual(pair.bufferDecoder.asUint8Array());
      });
    }
  }
});

describe('Writer.writeSfixed32 does', () => {
  let writer;
  beforeEach(() => {
    writer = new Writer();
  });

  it('encode empty array', () => {
    writer.writePackedSfixed32(1, []);
    expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer());
  });

  for (const pair of getSfixed32Pairs()) {
    it(`encode ${pair.name}`, () => {
      writer.writeSfixed32(1, pair.intValue);
      const buffer = new Uint8Array(writer.getAndResetResultBuffer());
      expect(buffer.length).toBe(5);
      // ensure we have a correct tag
      expect(buffer[0]).toEqual(0x0D);
      // Encoded values are stored right after the tag
      expect(buffer.subarray(1, 5)).toEqual(pair.bufferDecoder.asUint8Array());
    });
  }
});

describe('Writer.writeSfixed64 does', () => {
  let writer;
  beforeEach(() => {
    writer = new Writer();
  });

  for (const pair of getSfixed64Pairs()) {
    it(`encode ${pair.name}`, () => {
      writer.writeSfixed64(1, pair.longValue);
      const buffer = new Uint8Array(writer.getAndResetResultBuffer());
      expect(buffer.length).toBe(9);
      // ensure we have a correct tag
      expect(buffer[0]).toEqual(0x09);
      // Encoded values are stored right after the tag
      expect(buffer.subarray(1, 9)).toEqual(pair.bufferDecoder.asUint8Array());
    });
  }
});

describe('Writer.writeSint32 does', () => {
  let writer;
  beforeEach(() => {
    writer = new Writer();
  });

  for (const pair of getSint32Pairs()) {
    if (!pair.skip_writer) {
      it(`encode ${pair.name}`, () => {
        writer.writeSint32(1, pair.intValue);
        const buffer = new Uint8Array(writer.getAndResetResultBuffer());
        // ensure we have a correct tag
        expect(buffer[0]).toEqual(0x08);
        // Encoded values are stored right after the tag
        expect(buffer.subarray(1, buffer.length))
            .toEqual(pair.bufferDecoder.asUint8Array());
      });
    }
  }
});

describe('Writer.writeSint64 does', () => {
  let writer;
  beforeEach(() => {
    writer = new Writer();
  });

  for (const pair of getSint64Pairs()) {
    if (!pair.skip_writer) {
      it(`encode ${pair.name}`, () => {
        writer.writeSint64(1, pair.longValue);
        const buffer = new Uint8Array(writer.getAndResetResultBuffer());
        // ensure we have a correct tag
        expect(buffer[0]).toEqual(0x08);
        // Encoded values are stored right after the tag
        expect(buffer.subarray(1, buffer.length))
            .toEqual(pair.bufferDecoder.asUint8Array());
      });
    }
  }
});

describe('Writer.writeInt64 does', () => {
  let writer;
  beforeEach(() => {
    writer = new Writer();
  });

  for (const pair of getInt64Pairs()) {
    if (!pair.skip_writer) {
      it(`encode ${pair.name}`, () => {
        writer.writeInt64(1, pair.longValue);
        const buffer = new Uint8Array(writer.getAndResetResultBuffer());
        // ensure we have a correct tag
        expect(buffer[0]).toEqual(0x08);
        // Encoded values are stored right after the tag
        expect(buffer.subarray(1, buffer.length))
            .toEqual(pair.bufferDecoder.asUint8Array());
      });
    }
  }
});

describe('Writer.writeUint32 does', () => {
  let writer;
  beforeEach(() => {
    writer = new Writer();
  });

  for (const pair of getUint32Pairs()) {
    if (!pair.skip_writer) {
      it(`encode ${pair.name}`, () => {
        writer.writeUint32(1, pair.intValue);
        const buffer = new Uint8Array(writer.getAndResetResultBuffer());
        // ensure we have a correct tag
        expect(buffer[0]).toEqual(0x08);
        // Encoded values are stored right after the tag
        expect(buffer.subarray(1, buffer.length))
            .toEqual(pair.bufferDecoder.asUint8Array());
      });
    }
  }
});

describe('Writer.writeString does', () => {
  let writer;
  beforeEach(() => {
    writer = new Writer();
  });

  it('encode empty string', () => {
    writer.writeString(1, '');
    expect(writer.getAndResetResultBuffer())
        .toEqual(createArrayBuffer(
            1 << 3 | 0x02,  // tag (fieldnumber << 3 | (length delimited))
            0,              // length of the string
            ));
  });

  it('encode simple string', () => {
    writer.writeString(1, 'hello');
    expect(writer.getAndResetResultBuffer())
        .toEqual(createArrayBuffer(
            1 << 3 | 0x02,  // tag (fieldnumber << 3 | (length delimited))
            5,              // length of the string
            'h'.charCodeAt(0),
            'e'.charCodeAt(0),
            'l'.charCodeAt(0),
            'l'.charCodeAt(0),
            'o'.charCodeAt(0),
            ));
  });

  it('throw for invalid fieldnumber', () => {
    if (CHECK_BOUNDS) {
      expect(() => writer.writeString(-1, 'a'))
          .toThrowError('Field number is out of range: -1');
    } else {
      writer.writeString(-1, 'a');
      expect(new Uint8Array(writer.getAndResetResultBuffer()))
          .toEqual(new Uint8Array(createArrayBuffer(
              -6,  // invalid tag
              0xff,
              0xff,
              0xff,
              0x0f,
              1,  // string length
              'a'.charCodeAt(0),
              )));
    }
  });

  it('throw for null string value', () => {
    expect(
        () => writer.writeString(
            1, /** @type {string} */ (/** @type {*} */ (null))))
        .toThrow();
  });
});


/******************************************************************************
 *                        REPEATED FUNCTIONS
 ******************************************************************************/

describe('Writer.writePackedBool does', () => {
  let writer;
  beforeEach(() => {
    writer = new Writer();
  });

  it('encode empty array', () => {
    writer.writePackedBool(1, []);
    expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer());
  });

  for (const pair of getPackedBoolPairs()) {
    if (!pair.skip_writer) {
      it(`encode ${pair.name}`, () => {
        writer.writePackedBool(1, pair.boolValues);
        const buffer = new Uint8Array(writer.getAndResetResultBuffer());
        // ensure we have a correct tag
        expect(buffer[0]).toEqual(0x0A);
        // Encoded values are stored right after the tag
        expect(buffer.subarray(1, buffer.length))
            .toEqual(pair.bufferDecoder.asUint8Array());
      });
    }
  }
});

describe('Writer.writeRepeatedBool does', () => {
  let writer;
  beforeEach(() => {
    writer = new Writer();
  });

  it('encode empty array', () => {
    writer.writeRepeatedBool(1, []);
    expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer());
  });

  it('encode repeated unpacked boolean values', () => {
    const writer = new Writer();
    writer.writeRepeatedBool(1, [true, false]);
    expect(writer.getAndResetResultBuffer())
        .toEqual(createArrayBuffer(
            1 << 3 | 0x00,  // tag (fieldnumber << 3 | (varint))
            0x01,           // value[0]
            1 << 3 | 0x00,  // tag (fieldnumber << 3 | (varint))
            0x00,           // value[1]
            ));
  });
});

describe('Writer.writePackedDouble does', () => {
  let writer;
  beforeEach(() => {
    writer = new Writer();
  });

  it('encode empty array', () => {
    writer.writePackedDouble(1, []);
    expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer());
  });

  for (const pair of getPackedDoublePairs()) {
    if (!pair.skip_writer) {
      it(`encode ${pair.name}`, () => {
        writer.writePackedDouble(1, pair.doubleValues);
        const buffer = new Uint8Array(writer.getAndResetResultBuffer());
        // ensure we have a correct tag
        expect(buffer[0]).toEqual(0x0A);
        // Encoded values are stored right after the tag
        expect(buffer.subarray(1, buffer.length))
            .toEqual(pair.bufferDecoder.asUint8Array());
      });
    }
  }
});

describe('Writer.writePackedFixed32 does', () => {
  let writer;
  beforeEach(() => {
    writer = new Writer();
  });

  it('encode empty array', () => {
    writer.writePackedFixed32(1, []);
    expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer());
  });

  for (const pair of getPackedFixed32Pairs()) {
    if (!pair.skip_writer) {
      it(`encode ${pair.name}`, () => {
        writer.writePackedFixed32(1, pair.fixed32Values);
        const buffer = new Uint8Array(writer.getAndResetResultBuffer());
        // ensure we have a correct tag
        expect(buffer[0]).toEqual(0x0A);
        // Encoded values are stored right after the tag
        expect(buffer.subarray(1, buffer.length))
            .toEqual(pair.bufferDecoder.asUint8Array());
      });
    }
  }
});

describe('Writer.writePackedFloat does', () => {
  let writer;
  beforeEach(() => {
    writer = new Writer();
  });

  it('encode empty array', () => {
    writer.writePackedFloat(1, []);
    expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer());
  });

  for (const pair of getPackedFloatPairs()) {
    if (!pair.skip_writer) {
      it(`encode ${pair.name}`, () => {
        writer.writePackedFloat(1, pair.floatValues);
        const buffer = new Uint8Array(writer.getAndResetResultBuffer());
        // ensure we have a correct tag
        expect(buffer[0]).toEqual(0x0A);
        // Encoded values are stored right after the tag
        expect(buffer.subarray(1, buffer.length))
            .toEqual(pair.bufferDecoder.asUint8Array());
      });
    }
  }
});

describe('Writer.writePackedInt32 does', () => {
  let writer;
  beforeEach(() => {
    writer = new Writer();
  });

  it('encode empty array', () => {
    writer.writePackedInt32(1, []);
    expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer());
  });

  for (const pair of getPackedInt32Pairs()) {
    if (!pair.skip_writer) {
      it(`encode ${pair.name}`, () => {
        writer.writePackedInt32(1, pair.int32Values);
        const buffer = new Uint8Array(writer.getAndResetResultBuffer());
        // ensure we have a correct tag
        expect(buffer[0]).toEqual(0x0A);
        // Encoded values are stored right after the tag
        expect(buffer.subarray(1, buffer.length))
            .toEqual(pair.bufferDecoder.asUint8Array());
      });
    }
  }
});

describe('Writer.writePackedInt64 does', () => {
  let writer;
  beforeEach(() => {
    writer = new Writer();
  });

  it('encode empty array', () => {
    writer.writePackedInt64(1, []);
    expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer());
  });

  for (const pair of getPackedInt64Pairs()) {
    if (!pair.skip_writer) {
      it(`encode ${pair.name}`, () => {
        writer.writePackedInt64(1, pair.int64Values);
        const buffer = new Uint8Array(writer.getAndResetResultBuffer());
        // ensure we have a correct tag
        expect(buffer[0]).toEqual(0x0A);
        // Encoded values are stored right after the tag
        expect(buffer.subarray(1, buffer.length))
            .toEqual(pair.bufferDecoder.asUint8Array());
      });
    }
  }
});

describe('Writer.writePackedSfixed32 does', () => {
  let writer;
  beforeEach(() => {
    writer = new Writer();
  });

  it('encode empty array', () => {
    writer.writePackedSfixed32(1, []);
    expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer());
  });

  for (const pair of getPackedSfixed32Pairs()) {
    if (!pair.skip_writer) {
      it(`encode ${pair.name}`, () => {
        writer.writePackedSfixed32(1, pair.sfixed32Values);
        const buffer = new Uint8Array(writer.getAndResetResultBuffer());
        // ensure we have a correct tag
        expect(buffer[0]).toEqual(0x0A);
        // Encoded values are stored right after the tag
        expect(buffer.subarray(1, buffer.length))
            .toEqual(pair.bufferDecoder.asUint8Array());
      });
    }
  }
});

describe('Writer.writePackedSfixed64 does', () => {
  let writer;
  beforeEach(() => {
    writer = new Writer();
  });

  it('encode empty array', () => {
    writer.writePackedSfixed64(1, []);
    expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer());
  });

  for (const pair of getPackedSfixed64Pairs()) {
    if (!pair.skip_writer) {
      it(`encode ${pair.name}`, () => {
        writer.writePackedSfixed64(1, pair.sfixed64Values);
        const buffer = new Uint8Array(writer.getAndResetResultBuffer());
        // ensure we have a correct tag
        expect(buffer[0]).toEqual(0x0A);
        // Encoded values are stored right after the tag
        expect(buffer.subarray(1, buffer.length))
            .toEqual(pair.bufferDecoder.asUint8Array());
      });
    }
  }
});

describe('Writer.writePackedSint32 does', () => {
  let writer;
  beforeEach(() => {
    writer = new Writer();
  });

  it('encode empty array', () => {
    writer.writePackedSint32(1, []);
    expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer());
  });

  for (const pair of getPackedSint32Pairs()) {
    if (!pair.skip_writer) {
      it(`encode ${pair.name}`, () => {
        writer.writePackedSint32(1, pair.sint32Values);
        const buffer = new Uint8Array(writer.getAndResetResultBuffer());
        // ensure we have a correct tag
        expect(buffer[0]).toEqual(0x0A);
        // Encoded values are stored right after the tag
        expect(buffer.subarray(1, buffer.length))
            .toEqual(pair.bufferDecoder.asUint8Array());
      });
    }
  }
});

describe('Writer.writePackedSint64 does', () => {
  let writer;
  beforeEach(() => {
    writer = new Writer();
  });

  it('encode empty array', () => {
    writer.writePackedSint64(1, []);
    expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer());
  });

  for (const pair of getPackedSint64Pairs()) {
    if (!pair.skip_writer) {
      it(`encode ${pair.name}`, () => {
        writer.writePackedSint64(1, pair.sint64Values);
        const buffer = new Uint8Array(writer.getAndResetResultBuffer());
        // ensure we have a correct tag
        expect(buffer[0]).toEqual(0x0A);
        // Encoded values are stored right after the tag
        expect(buffer.subarray(1, buffer.length))
            .toEqual(pair.bufferDecoder.asUint8Array());
      });
    }
  }
});

describe('Writer.writePackedUint32 does', () => {
  let writer;
  beforeEach(() => {
    writer = new Writer();
  });

  it('encode empty array', () => {
    writer.writePackedUint32(1, []);
    expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer());
  });

  for (const pair of getPackedUint32Pairs()) {
    if (!pair.skip_writer) {
      it(`encode ${pair.name}`, () => {
        writer.writePackedUint32(1, pair.uint32Values);
        const buffer = new Uint8Array(writer.getAndResetResultBuffer());
        // ensure we have a correct tag
        expect(buffer[0]).toEqual(0x0A);
        // Encoded values are stored right after the tag
        expect(buffer.subarray(1, buffer.length))
            .toEqual(pair.bufferDecoder.asUint8Array());
      });
    }
  }
});

describe('Writer.writeRepeatedBytes does', () => {
  let writer;
  beforeEach(() => {
    writer = new Writer();
  });

  it('encode empty array', () => {
    writer.writeRepeatedBytes(1, []);
    expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer());
  });

  it('encode single value', () => {
    const value = createArrayBuffer(0x61);
    writer.writeRepeatedBytes(1, [ByteString.fromArrayBuffer(value)]);
    expect(writer.getAndResetResultBuffer())
        .toEqual(createArrayBuffer(
            0x0A,
            0x01,
            0x61,  // a
            ));
  });

  it('encode multiple values', () => {
    const value1 = createArrayBuffer(0x61);
    const value2 = createArrayBuffer(0x62);
    writer.writeRepeatedBytes(1, [
      ByteString.fromArrayBuffer(value1),
      ByteString.fromArrayBuffer(value2),
    ]);
    expect(writer.getAndResetResultBuffer())
        .toEqual(createArrayBuffer(
            0x0A,
            0x01,
            0x61,  // a
            0x0A,
            0x01,
            0x62,  // b
            ));
  });
});

describe('Writer.writeRepeatedString does', () => {
  let writer;
  beforeEach(() => {
    writer = new Writer();
  });

  it('encode empty array', () => {
    writer.writeRepeatedString(1, []);
    expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer());
  });

  it('encode single value', () => {
    writer.writeRepeatedString(1, ['a']);
    expect(writer.getAndResetResultBuffer())
        .toEqual(createArrayBuffer(
            0x0A,
            0x01,
            0x61,  // a
            ));
  });

  it('encode multiple values', () => {
    writer.writeRepeatedString(1, ['a', 'b']);
    expect(writer.getAndResetResultBuffer())
        .toEqual(createArrayBuffer(
            0x0A,
            0x01,
            0x61,  // a
            0x0A,
            0x01,
            0x62,  // b
            ));
  });
});
