Skip to content

Commit 17c3e39

Browse files
author
Alberto Iannaccone
committed
test monitor utils
1 parent 7063f92 commit 17c3e39

File tree

5 files changed

+176
-19
lines changed

5 files changed

+176
-19
lines changed

arduino-ide-extension/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@
102102
"download": "^7.1.0",
103103
"grpc_tools_node_protoc_ts": "^4.1.0",
104104
"mocha": "^7.0.0",
105+
"mockdate": "^3.0.5",
105106
"moment": "^2.24.0",
106107
"protoc": "^1.0.4",
107108
"shelljs": "^0.8.3",

arduino-ide-extension/src/browser/monitor/monitor-utils.ts

+10-10
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import { Line, SerialMonitorOutput } from './serial-monitor-send-output';
22

3-
export function messageToLines(
3+
export function messagesToLines(
44
messages: string[],
5-
prevLines: Line[],
5+
prevLines: Line[] = [],
6+
charCount = 0,
67
separator = '\n'
78
): [Line[], number] {
89
const linesToAdd: Line[] = prevLines.length
910
? [prevLines[prevLines.length - 1]]
10-
: [{ message: '', lineLen: 0 }];
11-
let charCount = 0;
11+
: [{ message: '' }];
1212

1313
for (const message of messages) {
1414
const messageLen = message.length;
@@ -20,12 +20,10 @@ export function messageToLines(
2020
linesToAdd.push({
2121
message,
2222
timestamp: new Date(),
23-
lineLen: messageLen,
2423
});
2524
} else {
2625
// concatenate to the last line
2726
linesToAdd[linesToAdd.length - 1].message += message;
28-
linesToAdd[linesToAdd.length - 1].lineLen += messageLen;
2927
if (!linesToAdd[linesToAdd.length - 1].timestamp) {
3028
linesToAdd[linesToAdd.length - 1].timestamp = new Date();
3129
}
@@ -38,12 +36,13 @@ export function messageToLines(
3836

3937
export function truncateLines(
4038
lines: Line[],
41-
charCount: number
39+
charCount: number,
40+
maxCharacters: number = SerialMonitorOutput.MAX_CHARACTERS
4241
): [Line[], number] {
43-
let charsToDelete = charCount - SerialMonitorOutput.MAX_CHARACTERS;
42+
let charsToDelete = charCount - maxCharacters;
4443
let lineIndex = 0;
45-
while (charsToDelete > 0) {
46-
const firstLineLength = lines[lineIndex]?.lineLen;
44+
while (charsToDelete > 0 || lineIndex > 0) {
45+
const firstLineLength = lines[lineIndex]?.message.length || 0;
4746

4847
if (charsToDelete >= firstLineLength) {
4948
// every time a full line to delete is found, move the index.
@@ -55,6 +54,7 @@ export function truncateLines(
5554

5655
// delete all previous lines
5756
lines.splice(0, lineIndex);
57+
lineIndex = 0;
5858

5959
const newFirstLine = lines[0]?.message?.substring(charsToDelete);
6060
const deletedCharsCount = firstLineLength - newFirstLine.length;

arduino-ide-extension/src/browser/monitor/serial-monitor-send-output.tsx

+7-9
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ import AutoSizer from 'react-virtualized-auto-sizer';
66
import { MonitorModel } from './monitor-model';
77
import { MonitorConnection } from './monitor-connection';
88
import dateFormat = require('dateformat');
9-
import { messageToLines, truncateLines } from './monitor-utils';
9+
import { messagesToLines, truncateLines } from './monitor-utils';
1010

11-
export type Line = { message: string; timestamp?: Date; lineLen: number };
11+
export type Line = { message: string; timestamp?: Date };
1212

1313
export class SerialMonitorOutput extends React.Component<
1414
SerialMonitorOutput.Props,
@@ -66,14 +66,12 @@ export class SerialMonitorOutput extends React.Component<
6666
this.scrollToBottom();
6767
this.toDisposeBeforeUnmount.pushAll([
6868
this.props.monitorConnection.onRead(({ messages }) => {
69-
const [newLines, charsToAddCount] = messageToLines(
69+
const [newLines, totalCharCount] = messagesToLines(
7070
messages,
71-
this.state.lines
72-
);
73-
const [lines, charCount] = truncateLines(
74-
newLines,
75-
this.state.charCount + charsToAddCount
71+
this.state.lines,
72+
this.state.charCount
7673
);
74+
const [lines, charCount] = truncateLines(newLines, totalCharCount);
7775

7876
this.setState({
7977
lines,
@@ -119,7 +117,7 @@ const Row = ({
119117
`${dateFormat(data.lines[index].timestamp, 'H:M:ss.l')} -> `) ||
120118
'';
121119
return (
122-
(data.lines[index].lineLen && (
120+
(data.lines[index].message?.length && (
123121
<div style={style}>
124122
{timestamp}
125123
{data.lines[index].message}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
import { expect } from 'chai';
2+
import {
3+
messagesToLines,
4+
truncateLines,
5+
} from '../../browser/monitor/monitor-utils';
6+
import { Line } from '../../browser/monitor/serial-monitor-send-output';
7+
import { set, reset } from 'mockdate';
8+
9+
type TestLine = {
10+
messages: string[];
11+
prevLines?: { lines: Line[]; charCount: number };
12+
expected: { lines: Line[]; charCount: number };
13+
expectedTruncated?: {
14+
lines: Line[];
15+
charCount: number;
16+
maxCharacters?: number;
17+
};
18+
};
19+
20+
const date = new Date();
21+
const testLines: TestLine[] = [
22+
{
23+
messages: ['Hello'],
24+
expected: { lines: [{ message: 'Hello' }], charCount: 5 },
25+
},
26+
{
27+
messages: ['Hello', 'Dog!'],
28+
expected: { lines: [{ message: 'HelloDog!' }], charCount: 9 },
29+
},
30+
{
31+
messages: ['Hello\n', 'Dog!'],
32+
expected: {
33+
lines: [{ message: 'Hello\n' }, { message: 'Dog!' }],
34+
charCount: 10,
35+
},
36+
},
37+
{
38+
messages: ['Dog!'],
39+
prevLines: { lines: [{ message: 'Hello\n' }], charCount: 6 },
40+
expected: {
41+
lines: [{ message: 'Hello\n' }, { message: 'Dog!' }],
42+
charCount: 10,
43+
},
44+
},
45+
{
46+
messages: [' Dog!\n', " Who's a good ", 'boy?\n', "You're a good boy!"],
47+
prevLines: { lines: [{ message: 'Hello' }], charCount: 5 },
48+
expected: {
49+
lines: [
50+
{ message: 'Hello Dog!\n' },
51+
{ message: " Who's a good boy?\n" },
52+
{ message: "You're a good boy!" },
53+
],
54+
charCount: 48,
55+
},
56+
expectedTruncated: {
57+
maxCharacters: 20,
58+
charCount: 20,
59+
lines: [{ message: '?\n' }, { message: "You're a good boy!" }],
60+
},
61+
},
62+
{
63+
messages: ['boy?\n', "You're a good boy!"],
64+
prevLines: {
65+
lines: [{ message: 'Hello Dog!\n' }, { message: " Who's a good " }],
66+
charCount: 25,
67+
},
68+
expected: {
69+
lines: [
70+
{ message: 'Hello Dog!\n' },
71+
{ message: " Who's a good boy?\n" },
72+
{ message: "You're a good boy!" },
73+
],
74+
charCount: 48,
75+
},
76+
expectedTruncated: {
77+
maxCharacters: 20,
78+
charCount: 20,
79+
lines: [{ message: '?\n' }, { message: "You're a good boy!" }],
80+
},
81+
},
82+
{
83+
messages: ["Who's a good boy?\n", 'Yo'],
84+
prevLines: {
85+
lines: [{ message: 'Hello Dog!\n' }],
86+
charCount: 11,
87+
},
88+
expected: {
89+
lines: [
90+
{ message: 'Hello Dog!\n' },
91+
{ message: "Who's a good boy?\n" },
92+
{ message: 'Yo' },
93+
],
94+
charCount: 31,
95+
},
96+
expectedTruncated: {
97+
maxCharacters: 20,
98+
charCount: 20,
99+
lines: [{ message: "Who's a good boy?\n" }, { message: 'Yo' }],
100+
},
101+
},
102+
];
103+
104+
testLines.forEach((t) =>
105+
[...t.expected.lines, ...(t.prevLines?.lines || [])].forEach(
106+
(l) => (l.timestamp = date)
107+
)
108+
);
109+
110+
describe.only('Monitor Utils', () => {
111+
beforeEach(() => {
112+
set(date);
113+
});
114+
115+
afterEach(() => {
116+
reset();
117+
});
118+
119+
testLines.forEach((testLine) => {
120+
context('when converting messages', () => {
121+
it('should give the right result', () => {
122+
const [newLines, addedCharCount] = messagesToLines(
123+
testLine.messages,
124+
testLine.prevLines?.lines,
125+
testLine.prevLines?.charCount
126+
);
127+
newLines.forEach((line, index) => {
128+
expect(line.message).to.equal(testLine.expected.lines[index].message);
129+
expect(line.timestamp).to.deep.equal(
130+
testLine.expected.lines[index].timestamp
131+
);
132+
});
133+
expect(addedCharCount).to.equal(testLine.expected.charCount);
134+
135+
const [truncatedLines, totalCharCount] = truncateLines(
136+
newLines,
137+
addedCharCount,
138+
testLine.expectedTruncated?.maxCharacters
139+
);
140+
let charCount = 0;
141+
if (testLine.expectedTruncated) {
142+
truncatedLines.forEach((line, index) => {
143+
expect(line.message).to.equal(
144+
testLine.expectedTruncated?.lines[index].message
145+
);
146+
charCount += line.message.length;
147+
});
148+
expect(totalCharCount).to.equal(charCount);
149+
}
150+
});
151+
});
152+
});
153+
});

yarn.lock

+5
Original file line numberDiff line numberDiff line change
@@ -11743,6 +11743,11 @@ mocha@^7.0.0:
1174311743
yargs-parser "13.1.2"
1174411744
yargs-unparser "1.6.0"
1174511745

11746+
mockdate@^3.0.5:
11747+
version "3.0.5"
11748+
resolved "https://registry.yarnpkg.com/mockdate/-/mockdate-3.0.5.tgz#789be686deb3149e7df2b663d2bc4392bc3284fb"
11749+
integrity sha512-iniQP4rj1FhBdBYS/+eQv7j1tadJ9lJtdzgOpvsOHng/GbcDh2Fhdeq+ZRldrPYdXvCyfFUmFeEwEGXZB5I/AQ==
11750+
1174611751
modify-values@^1.0.0:
1174711752
version "1.0.1"
1174811753
resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022"

0 commit comments

Comments
 (0)