aboutsummaryrefslogtreecommitdiff
path: root/pw_hdlc/ts/encoder_test.ts
blob: 23451bcfb029109bb60d864b5357ab60d7b69300 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
// Copyright 2022 The Pigweed Authors
//
// 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
//
//     https://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.

/* eslint-env browser */

import { Encoder } from './encoder';
import * as protocol from './protocol';
import * as util from './util';

const FLAG = Uint8Array.from([protocol.FLAG]);

function withFCS(data: Uint8Array): Uint8Array {
  return util.concatenate(data, protocol.frameCheckSequence(data));
}

function withFlags(data: Uint8Array): Uint8Array {
  return util.concatenate(FLAG, data, FLAG);
}

describe('Encoder', () => {
  let encoder: Encoder;
  let textEncoder: TextEncoder;

  beforeEach(() => {
    encoder = new Encoder();
    textEncoder = new TextEncoder();
  });

  it('creates frame for empty data', () => {
    const data = textEncoder.encode('');
    expect(encoder.uiFrame(0, data)).toEqual(
      withFlags(withFCS(new Uint8Array([0x01, 0x03]))),
    );
    expect(encoder.uiFrame(0x1a, data)).toEqual(
      withFlags(withFCS(new Uint8Array([0x35, 0x03]))),
    );
    expect(encoder.uiFrame(0x1a, data)).toEqual(
      withFlags(withFCS(textEncoder.encode('\x35\x03'))),
    );
  });

  it('creates frame for one byte', () => {
    const data = textEncoder.encode('A');
    expect(encoder.uiFrame(0, data)).toEqual(
      withFlags(withFCS(textEncoder.encode('\x01\x03A'))),
    );
  });

  it('creates frame for multibyte data', () => {
    const data = textEncoder.encode('123456789');
    expect(encoder.uiFrame(0, data)).toEqual(
      withFlags(withFCS(textEncoder.encode('\x01\x03123456789'))),
    );
  });

  it('creates frame for multibyte data with address', () => {
    const data = textEncoder.encode('123456789');
    expect(encoder.uiFrame(128, data)).toEqual(
      withFlags(withFCS(textEncoder.encode('\x00\x03\x03123456789'))),
    );
  });

  it('creates frame for data with escape sequence', () => {
    const data = textEncoder.encode('\x7d');
    const expectedContent = util.concatenate(
      textEncoder.encode('\x7d\x5d\x03\x7d\x5d'),
      protocol.frameCheckSequence(textEncoder.encode('\x7d\x03\x7d')),
    );
    expect(encoder.uiFrame(0x3e, data)).toEqual(withFlags(expectedContent));

    const data2 = textEncoder.encode('A\x7e\x7dBC');
    const expectedContent2 = util.concatenate(
      textEncoder.encode('\x7d\x5d\x03A\x7d\x5e\x7d\x5dBC'),
      protocol.frameCheckSequence(textEncoder.encode('\x7d\x03A\x7e\x7dBC')),
    );
    expect(encoder.uiFrame(0x3e, data2)).toEqual(withFlags(expectedContent2));
  });

  it('Computes frameCheckSequence correctly', () => {
    expect(
      protocol.frameCheckSequence(textEncoder.encode('\x7d\x03A\x7e\x7dBC')),
    ).toEqual(new Uint8Array([195, 124, 135, 9]));
    expect(
      protocol.frameCheckSequence(textEncoder.encode('\x7d\x5d\x03\x7d\x5d')),
    ).toEqual(new Uint8Array([183, 144, 10, 115]));
    expect(
      protocol.frameCheckSequence(textEncoder.encode('\x7d\x03\x7d')),
    ).toEqual(new Uint8Array([83, 124, 241, 166]));
    expect(
      protocol.frameCheckSequence(textEncoder.encode('hello pigweed')),
    ).toEqual(new Uint8Array([34, 22, 236, 2]));
  });
});