Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 2bca1e1

Browse files
committed
serial-service tests
1 parent 7d10e89 commit 2bca1e1

File tree

5 files changed

+261
-55
lines changed

5 files changed

+261
-55
lines changed

‎arduino-ide-extension/package.json‎

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,11 @@
1919
"test:watch": "mocha --watch --watch-files lib \"./lib/test/**/*.test.js\""
2020
},
2121
"dependencies": {
22-
"arduino-serial-plotter-webapp": "0.0.15",
2322
"@grpc/grpc-js": "^1.3.7",
2423
"@theia/application-package": "1.19.0",
2524
"@theia/core": "1.19.0",
2625
"@theia/editor": "1.19.0",
27-
"@theia/editor-preview": "1.19.0",
26+
"@theia/editor-preview": "1.19.0",
2827
"@theia/filesystem": "1.19.0",
2928
"@theia/git": "1.19.0",
3029
"@theia/keymaps": "1.19.0",
@@ -53,10 +52,10 @@
5352
"@types/ps-tree": "^1.1.0",
5453
"@types/react-select": "^3.0.0",
5554
"@types/react-tabs": "^2.3.2",
56-
"@types/sinon": "^7.5.2",
5755
"@types/temp": "^0.8.34",
5856
"@types/which": "^1.3.1",
5957
"ajv": "^6.5.3",
58+
"arduino-serial-plotter-webapp": "0.0.15",
6059
"async-mutex": "^0.3.0",
6160
"atob": "^2.1.2",
6261
"auth0-js": "^9.14.0",
@@ -97,6 +96,8 @@
9796
"@types/chai-string": "^1.4.2",
9897
"@types/mocha": "^5.2.7",
9998
"@types/react-window": "^1.8.5",
99+
"@types/sinon": "^10.0.6",
100+
"@types/sinon-chai": "^3.2.6",
100101
"chai": "^4.2.0",
101102
"chai-string": "^1.5.0",
102103
"decompress": "^4.2.0",
@@ -109,7 +110,8 @@
109110
"moment": "^2.24.0",
110111
"protoc": "^1.0.4",
111112
"shelljs": "^0.8.3",
112-
"sinon": "^9.0.1",
113+
"sinon": "^12.0.1",
114+
"sinon-chai": "^3.7.0",
113115
"typemoq": "^2.1.0",
114116
"uuid": "^3.2.1",
115117
"yargs": "^11.1.0"

‎arduino-ide-extension/src/node/serial/serial-service-impl.ts‎

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -63,16 +63,6 @@ namespace ErrorWithCode {
6363

6464
@injectable()
6565
export class SerialServiceImpl implements SerialService {
66-
@named(SerialServiceName)
67-
@inject(ILogger)
68-
protected readonly logger: ILogger;
69-
70-
@inject(MonitorClientProvider)
71-
protected readonly serialClientProvider: MonitorClientProvider;
72-
73-
@inject(WebSocketService)
74-
protected readonly webSocketService: WebSocketService;
75-
7666
protected theiaFEClient?: SerialServiceClient;
7767
protected serialConfig?: SerialConfig;
7868

@@ -88,6 +78,18 @@ export class SerialServiceImpl implements SerialService {
8878

8979
uploadInProgress = false;
9080

81+
constructor(
82+
@inject(ILogger)
83+
@named(SerialServiceName)
84+
protected readonly logger: ILogger,
85+
86+
@inject(MonitorClientProvider)
87+
protected readonly serialClientProvider: MonitorClientProvider,
88+
89+
@inject(WebSocketService)
90+
protected readonly webSocketService: WebSocketService
91+
) {}
92+
9193
async isSerialPortOpen(): Promise<boolean> {
9294
return !!this.serialConnection;
9395
}
@@ -115,7 +117,6 @@ export class SerialServiceImpl implements SerialService {
115117
public async connectSerialIfRequired(): Promise<void> {
116118
if (this.uploadInProgress) return;
117119
const clients = await this.clientsAttached();
118-
this.logger.info(`WS clients: ${clients}`);
119120
clients > 0 ? await this.connect() : await this.disconnect();
120121
}
121122

@@ -144,7 +145,7 @@ export class SerialServiceImpl implements SerialService {
144145
this.webSocketService.sendMessage(JSON.stringify(msg));
145146
}
146147

147-
async connect(): Promise<Status> {
148+
privateasync connect(): Promise<Status> {
148149
if (!this.serialConfig) {
149150
return Status.CONFIG_MISSING;
150151
}
@@ -155,8 +156,6 @@ export class SerialServiceImpl implements SerialService {
155156
)} on port ${Port.toString(this.serialConfig.port)}...`
156157
);
157158

158-
// check if the board/port is available
159-
160159
if (this.serialConnection) {
161160
return Status.ALREADY_CONNECTED;
162161
}
@@ -275,7 +274,9 @@ export class SerialServiceImpl implements SerialService {
275274
`<<< Serial connection created for ${boardName} on port ${portName}.`
276275
);
277276
resolve(Status.OK);
277+
return;
278278
});
279+
resolve(Status.NOT_CONNECTED);
279280
return;
280281
}
281282
this.disconnect().then(() => resolve(Status.NOT_CONNECTED));
@@ -299,12 +300,14 @@ export class SerialServiceImpl implements SerialService {
299300
reason &&
300301
reason.code === SerialError.ErrorCodes.CLIENT_CANCEL
301302
) {
302-
return Status.OK;
303+
resolve(Status.OK);
304+
return;
303305
}
304306
this.logger.info('>>> Disposing serial connection...');
305307
if (!this.serialConnection) {
306308
this.logger.warn('<<< Not connected. Nothing to dispose.');
307-
return Status.NOT_CONNECTED;
309+
resolve(Status.NOT_CONNECTED);
310+
return;
308311
}
309312
const { duplex, config } = this.serialConnection;
310313

‎arduino-ide-extension/src/test/browser/serial-connection-manager.test.ts‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,13 @@
100100
// return { dispose: () => {}};
101101
// });
102102

103+
// serialServiceClient
104+
// .setup((mock) => mock.onWebSocketChanged(It.isAny()))
105+
// .returns((h) => {
106+
// handleWebSocketChanged = h;
107+
// return { dispose: () => {}};
108+
// });
109+
103110
// serialService
104111
// .setup((m) => m.disconnect())
105112
// .returns(() => Promise.resolve(Status.OK));
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
import { MonitorServiceClient } from './../../node/cli-protocol/cc/arduino/cli/monitor/v1/monitor_grpc_pb.d';
2+
import { SerialServiceImpl } from './../../node/serial/serial-service-impl';
3+
import { IMock, It, Mock } from 'typemoq';
4+
import { createSandbox } from 'sinon';
5+
import * as sinonChai from 'sinon-chai';
6+
import { expect, use } from 'chai';
7+
use(sinonChai);
8+
9+
import { ILogger } from '@theia/core/lib/common/logger';
10+
import { MonitorClientProvider } from '../../node/serial/monitor-client-provider';
11+
import { WebSocketService } from '../../node/web-socket/web-socket-service';
12+
import { Status } from '../../common/protocol';
13+
14+
describe.only('SerialServiceImpl', () => {
15+
let subject: SerialServiceImpl;
16+
17+
let logger: IMock<ILogger>;
18+
let serialClientProvider: IMock<MonitorClientProvider>;
19+
let webSocketService: IMock<WebSocketService>;
20+
21+
beforeEach(() => {
22+
logger = Mock.ofType<ILogger>();
23+
logger.setup((b) => b.info(It.isAnyString()));
24+
logger.setup((b) => b.warn(It.isAnyString()));
25+
logger.setup((b) => b.error(It.isAnyString()));
26+
27+
serialClientProvider = Mock.ofType<MonitorClientProvider>();
28+
webSocketService = Mock.ofType<WebSocketService>();
29+
30+
subject = new SerialServiceImpl(
31+
logger.object,
32+
serialClientProvider.object,
33+
webSocketService.object
34+
);
35+
});
36+
37+
context('when a serial connection is requested', () => {
38+
const sandbox = createSandbox();
39+
beforeEach(() => {
40+
subject.uploadInProgress = false;
41+
sandbox.spy(subject, 'disconnect');
42+
sandbox.spy(subject, 'updateWsConfigParam');
43+
});
44+
45+
afterEach(function () {
46+
sandbox.restore();
47+
});
48+
49+
context('and an upload is in progress', () => {
50+
beforeEach(async () => {
51+
subject.uploadInProgress = true;
52+
});
53+
54+
it('should not change the connection status', async () => {
55+
await subject.connectSerialIfRequired();
56+
expect(subject.disconnect).to.have.callCount(0);
57+
});
58+
});
59+
60+
context('and there is no upload in progress', () => {
61+
beforeEach(async () => {
62+
subject.uploadInProgress = false;
63+
});
64+
65+
context('and there are 0 attached ws clients', () => {
66+
it('should disconnect', async () => {
67+
await subject.connectSerialIfRequired();
68+
expect(subject.disconnect).to.have.been.calledOnce;
69+
});
70+
});
71+
72+
context('and there are > 0 attached ws clients', () => {
73+
beforeEach(() => {
74+
webSocketService
75+
.setup((b) => b.getConnectedClientsNumber())
76+
.returns(() => 1);
77+
});
78+
79+
it('should not call the disconenct', async () => {
80+
await subject.connectSerialIfRequired();
81+
expect(subject.disconnect).to.have.callCount(0);
82+
});
83+
});
84+
});
85+
});
86+
87+
context('when a disconnection is requested', () => {
88+
const sandbox = createSandbox();
89+
beforeEach(() => {});
90+
91+
afterEach(function () {
92+
sandbox.restore();
93+
});
94+
95+
context('and a serialConnection is not set', () => {
96+
it('should return a NOT_CONNECTED status', async () => {
97+
const status = await subject.disconnect();
98+
expect(status).to.be.equal(Status.NOT_CONNECTED);
99+
});
100+
});
101+
102+
context('and a serialConnection is set', async () => {
103+
beforeEach(async () => {
104+
sandbox.spy(subject, 'updateWsConfigParam');
105+
await subject.disconnect();
106+
});
107+
108+
it('should dispose the serialConnection', async () => {
109+
const serialConnectionOpen = await subject.isSerialPortOpen();
110+
expect(serialConnectionOpen).to.be.false;
111+
});
112+
113+
it('should call updateWsConfigParam with disconnected status', async () => {
114+
expect(subject.updateWsConfigParam).to.be.calledWith({
115+
connected: false,
116+
});
117+
});
118+
});
119+
});
120+
121+
context('when a new config is passed in', () => {
122+
const sandbox = createSandbox();
123+
beforeEach(async () => {
124+
subject.uploadInProgress = false;
125+
webSocketService
126+
.setup((b) => b.getConnectedClientsNumber())
127+
.returns(() => 1);
128+
129+
serialClientProvider
130+
.setup((b) => b.client())
131+
.returns(async () => {
132+
return {
133+
streamingOpen: () => {
134+
return {
135+
on: (str: string, cb: any) => {},
136+
write: (chunk: any, cb: any) => {},
137+
cancel: () => {},
138+
};
139+
},
140+
} as MonitorServiceClient;
141+
});
142+
143+
sandbox.spy(subject, 'disconnect');
144+
sandbox.spy(subject, 'updateWsConfigParam');
145+
146+
await subject.setSerialConfig({
147+
board: { name: 'test' },
148+
port: { address: 'test', protocol: 'test' },
149+
});
150+
});
151+
152+
afterEach(function () {
153+
sandbox.restore();
154+
});
155+
156+
it('should disconnect from previous connection', async () => {
157+
expect(subject.disconnect).to.be.called;
158+
});
159+
160+
it('should create the serialConnection', async () => {
161+
const serialConnectionOpen = await subject.isSerialPortOpen();
162+
expect(serialConnectionOpen).to.be.true;
163+
});
164+
});
165+
});

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /