Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(220)

Side by Side Diff: third_party/WebKit/LayoutTests/usb/resources/usb-helpers.js

Issue 1730403006: Basic layout tests for WebUSB. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix Mojo tests that depend on extra module loading. Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 'use strict';
2
3 // TODO(reillyg): Remove when jyasskin upstreams this to testharness.js:
4 // https://crbug.com/509058.
5 function callWithKeyDown(functionCalledOnKeyPress) {
6 return new Promise(resolve => {
7 function onKeyPress() {
8 document.removeEventListener('keypress', onKeyPress, false);
9 resolve(functionCalledOnKeyPress());
10 }
11 document.addEventListener('keypress', onKeyPress, false);
12
13 eventSender.keyDown(' ', []);
14 });
15 }
16
17 function usbMocks(mojo) {
18 return define('USB Mocks', [
19 'components/webusb/public/interfaces/webusb_permission_bubble.mojom',
20 'device/usb/public/interfaces/device_manager.mojom',
21 'device/usb/public/interfaces/device.mojom',
22 ], (permissionBubble, deviceManager, device, permissionProvider) => {
23 function assertDeviceInfoEquals(device, info) {
24 assert_equals(device.guid, info.guid);
25 assert_equals(device.usbVersionMajor, info.usb_version_major);
26 assert_equals(device.usbVersionMinor, info.usb_version_minor);
27 assert_equals(device.usbVersionSubminor, info.usb_version_subminor);
28 assert_equals(device.deviceClass, info.class_code);
29 assert_equals(device.deviceSubclass, info.subclass_code);
30 assert_equals(device.deviceProtocol, info.protocol_code);
31 assert_equals(device.vendorId, info.vendor_id);
32 assert_equals(device.productId, info.product_id);
33 assert_equals(device.deviceVersionMajor, info.device_version_major);
34 assert_equals(device.deviceVersionMinor, info.device_version_minor);
35 assert_equals(device.deviceVersionSubminor,
36 info.device_version_subminor);
37 assert_equals(device.manufacturerName, info.manufacturer_name);
38 assert_equals(device.productName, info.product_name);
39 assert_equals(device.serialNumber, info.serial_number);
40 assert_equals(device.configurations.length,
41 info.configurations.length);
42 for (var i = 0; i < device.configurations.length; ++i) {
43 assertConfigurationInfoEquals(device.configurations[i],
44 info.configurations[i]);
45 }
46 };
47
48 function assertConfigurationInfoEquals(configuration, info) {
49 assert_equals(configuration.configurationValue,
50 info.configuration_value);
51 assert_equals(configuration.configurationName,
52 info.configuration_name);
53 assert_equals(configuration.interfaces.length,
54 info.interfaces.length);
55 for (var i = 0; i < configuration.interfaces.length; ++i) {
56 assertInterfaceInfoEquals(configuration.interfaces[i],
57 info.interfaces[i]);
58 }
59 };
60
61 function assertInterfaceInfoEquals(iface, info) {
62 assert_equals(iface.interfaceNumber, info.interface_number);
63 assert_equals(iface.alternates.length, info.alternates.length);
64 for (var i = 0; i < iface.alternates.length; ++i) {
65 assertAlternateInfoEquals(iface.alternates[i], info.alternates[i]);
66 }
67 };
68
69 function assertAlternateInfoEquals(alternate, info) {
70 assert_equals(alternate.alternateSetting, info.alternate_setting);
71 assert_equals(alternate.interfaceClass, info.class_code);
72 assert_equals(alternate.interfaceSubclass, info.subclass_code);
73 assert_equals(alternate.interfaceProtocol, info.protocol_code);
74 assert_equals(alternate.interfaceName, info.interface_name);
75 assert_equals(alternate.endpoints.length, info.endpoints.length);
76 for (var i = 0; i < alternate.endpoints.length; ++i) {
77 assertEndpointInfoEquals(alternate.endpoints[i], info.endpoints[i]);
78 }
79 }
80
81 function assertEndpointInfoEquals(endpoint, info) {
82 var direction;
83 switch (info.direction) {
84 case device.TransferDirection.INBOUND:
85 direction = 'in';
86 break;
87 case device.TransferDirection.OUTBOUND:
88 direction = 'out';
89 break;
90 }
91
92 var type;
93 switch (info.type) {
94 case device.EndpointType.BULK:
95 type = 'bulk';
96 break;
97 case device.EndpointType.INTERRUPT:
98 type = 'interrupt';
99 break;
100 case device.EndpointType.ISOCHRONOUS:
101 type = 'isochronous';
102 break;
103 }
104
105 assert_equals(endpoint.endpointNumber, info.endpoint_number);
106 assert_equals(endpoint.direction, direction);
107 assert_equals(endpoint.type, type);
108 assert_equals(endpoint.packetSize, info.packet_size);
109 }
110
111 class MockDevice extends device.Device.stubClass {
112 constructor(info, pipe) {
113 super();
114 this.info_ = info;
115 this.pipe_ = pipe;
116 this.router_ = new mojo.router.Router(pipe);
117 this.router_.setIncomingReceiver(this);
118 this.opened_ = false;
119 this.currentConfiguration_ = undefined;
120 this.claimedInterfaces_ = new Map();
121 }
122
123 getDeviceInfo() {
124 return Promise.resolve({ info: this.info_ });
125 }
126
127 getConfiguration() {
128 if (this.currentConfiguration_ === undefined) {
129 return Promise.resolve({ value: 0 });
130 } else {
131 return Promise.resolve({
132 value: this.currentConfiguration_.configuration_value });
133 }
134 }
135
136 open() {
137 // TODO(reillyg): Check if the device is opened and return
138 // OpenDeviceError.ALREADY_OPEN.
139 this.opened_ = true;
140 return Promise.resolve({ error: device.OpenDeviceError.OK });
141 }
142
143 close() {
144 this.opened_ = false;
145 return Promise.resolve({});
146 }
147
148 setConfiguration(value) {
149 if (!this.opened_)
150 return Promise.resolve({ success: false });
151
152 let selected_configuration = this.info_.configurations.find(
153 configuration => configuration.configuration_value == value);
154 if (selected_configuration !== undefined) {
155 this.currentConfiguration_ = selected_configuration;
156 return Promise.resolve({ success: true });
157 } else {
158 return Promise.resolve({ success: false });
159 }
160 }
161
162 claimInterface(interfaceNumber) {
163 if (!this.opened_)
164 return Promise.resolve({ success: false });
165
166 if (this.currentConfiguration_ === undefined)
167 return Promise.resolve({ success: false });
168
169 if (this.claimedInterfaces_.has(interfaceNumber))
170 return Promise.resolve({ success: false });
171
172 if (this.currentConfiguration_.interfaces.some(
173 iface => iface.interface_number == interfaceNumber)) {
174 this.claimedInterfaces_.set(interfaceNumber, 0);
175 return Promise.resolve({ success: true });
176 } else {
177 return Promise.resolve({ success: false });
178 }
179 }
180
181 releaseInterface(interfaceNumber) {
182 if (!this.opened_)
183 return Promise.resolve({ success: false });
184
185 if (this.currentConfiguration_ === undefined)
186 return Promise.resolve({ success: false });
187
188 if (this.claimedInterfaces_.has(interfaceNumber)) {
189 this.claimedInterfaces_.delete(interfaceNumber);
190 return Promise.resolve({ success: true });
191 } else {
192 return Promise.resolve({ success: false });
193 }
194 }
195
196 setInterfaceAlternateSetting(interfaceNumber, alternateSetting) {
197 if (!this.opened_ || this.currentConfiguration_ === undefined)
198 return Promise.resolve({ success: false });
199
200 if (!this.claimedInterfaces_.has(interfaceNumber))
201 return Promise.resolve({ success: false });
202
203 let iface = this.currentConfiguration_.interfaces.find(
204 iface => iface.interface_number == interfaceNumber);
205 if (iface === undefined)
206 return Promise.resolve({ success: false });
207
208 if (iface.alternates.some(
209 x => x.alternate_setting == alternateSetting)) {
210 this.claimedInterfaces_.set(interfaceNumber, alternateSetting);
211 return Promise.resolve({ success: true });
212 } else {
213 return Promise.resolve({ success: false });
214 }
215 }
216
217 reset() {
218 return Promise.resolve({ success: this.opened_ });
219 }
220
221 clearHalt(endpoint) {
222 // TODO(reillyg): Check that endpoint is valid.
223 return Promise.resolve({ success: this.opened_ });
224 }
225
226 controlTransferIn(params, length, timeout) {
227 return Promise.resolve({
228 status: device.TransferStatus.OK,
229 data: [length >> 8, length & 0xff, params.request, params.value >> 8,
230 params.value & 0xff, params.index >> 8, params.index & 0xff]
231 });
232 }
233
234 controlTransferOut(params, data, timeout) {
235 return Promise.resolve({
236 status: device.TransferStatus.OK,
237 bytesWritten: data.byteLength
238 });
239 }
240
241 genericTransferIn(endpointNumber, length, timeout) {
242 // TODO(reillyg): Check that endpoint is valid.
243 let data = new Array(length);
244 for (let i = 0; i < length; ++i)
245 data[i] = i & 0xff;
246 return Promise.resolve({
247 status: device.TransferStatus.OK,
248 data: data
249 });
250 }
251
252 genericTransferOut(endpointNumber, data, timeout) {
253 // TODO(reillyg): Check that endpoint is valid.
254 return Promise.resolve({
255 status: device.TransferStatus.OK,
256 bytesWritten: data.byteLength
257 });
258 }
259
260 isochronousTransferIn(endpointNumber, packetLengths, timeout) {
261 // TODO(reillyg): Check that endpoint is valid.
262 let data = new Array(packetLengths.reduce((a, b) => a + b, 0));
263 let dataOffset = 0;
264 let packets = new Array(packetLengths.length);
265 for (let i = 0; i < packetLengths.length; ++i) {
266 for (let j = 0; j < packetLengths[i]; ++j)
267 data[dataOffset++] = j & 0xff;
268 packets[i] = {
269 length: packetLengths[i],
270 transferred_length: packetLengths[i],
271 status: device.TransferStatus.OK
272 };
273 }
274 return Promise.resolve({ data: data, packets: packets });
275 }
276
277 isochronousTransferOut(endpointNumber, data, packetLengths, timeout) {
278 // TODO(reillyg): Check that endpoint is valid.
279 let packets = new Array(packetLengths.length);
280 for (let i = 0; i < packetLengths.length; ++i) {
281 packets[i] = {
282 length: packetLengths[i],
283 transferred_length: packetLengths[i],
284 status: device.TransferStatus.OK
285 };
286 }
287 return Promise.resolve({ packets: packets });
288 }
289 };
290
291 class MockDeviceManager extends deviceManager.DeviceManager.stubClass {
292 constructor() {
293 super();
294 this.router_ = null;
295 this.mockDevices_ = new Map();
296 this.addedDevices_ = [];
297 this.removedDevices_ = [];
298 this.deviceChangePromiseResolvers_ = [];
299 }
300
301 reset() {
302 this.mockDevices_.forEach(device => {
303 for (var handle of device.handles)
304 mojo.core.close(handle.pipe_);
305 this.removedDevices_.push(device.info);
306 });
307 this.mockDevices_.clear();
308 this.maybeResolveDeviceChangePromise();
309 }
310
311 addMockDevice(info) {
312 let device = {
313 info: info,
314 handles: []
315 };
316 this.mockDevices_.set(info.guid, device);
317 this.addedDevices_.push(info);
318 this.maybeResolveDeviceChangePromise();
319 }
320
321 removeMockDevice(info) {
322 let device = this.mockDevices_.get(info.guid);
323 for (var handle of device.handles)
324 mojo.core.close(handle.pipe_);
325 this.mockDevices_.delete(info.guid);
326 this.removedDevices_.push(info);
327 this.maybeResolveDeviceChangePromise();
328 }
329
330 bindToPipe(pipe) {
331 assert_equals(this.router_, null);
332 this.router_ = new mojo.router.Router(pipe);
333 this.router_.setIncomingReceiver(this);
334 }
335
336 getDevices(options) {
337 let devices = [];
338 this.mockDevices_.forEach(device => {
339 devices.push(device.info);
340 });
341 return Promise.resolve({ results: devices });
342 }
343
344 getDeviceChanges() {
345 let promise = new Promise((resolve, reject) => {
346 this.deviceChangePromiseResolvers_.push(resolve);
347 });
348 this.maybeResolveDeviceChangePromise();
349 return promise;
350 }
351
352 maybeResolveDeviceChangePromise() {
353 if (this.addedDevices_.length == 0 &&
354 this.removedDevices_.length == 0) {
355 return;
356 }
357
358 let resolve = this.deviceChangePromiseResolvers_.shift();
359 if (resolve === undefined)
360 return;
361
362 resolve({
363 changes: {
364 devices_added: this.addedDevices_,
365 devices_removed: this.removedDevices_
366 }
367 });
368 this.addedDevices_ = [];
369 this.removedDevices_ = [];
370 }
371
372 getDevice(guid, pipe) {
373 let device = this.mockDevices_.get(guid);
374 if (device !== undefined) {
375 var mock = new MockDevice(device.info, pipe);
376 device.handles.push(mock);
377 }
378 }
379 }
380
381 class MockPermissionBubble
382 extends permissionBubble.WebUsbPermissionBubble.stubClass {
383 constructor() {
384 super();
385 this.router_ = null;
386 this.chosenDevice_ = null;
387 }
388
389 bindToPipe(pipe) {
390 assert_equals(this.router_, null);
391 this.router_ = new mojo.router.Router(pipe);
392 this.router_.setIncomingReceiver(this);
393 }
394
395 setChosenDevice(deviceInfo) {
396 this.chosenDeviceInfo_ = deviceInfo;
397 }
398
399 getPermission(deviceFilters) {
400 return Promise.resolve({ result: this.chosenDeviceInfo_ });
401 }
402 }
403
404 let mockDeviceManager = new MockDeviceManager;
405 mojo.serviceRegistry.addServiceOverrideForTesting(
406 deviceManager.DeviceManager.name,
407 pipe => {
408 mockDeviceManager.bindToPipe(pipe);
409 });
410
411 let mockPermissionBubble = new MockPermissionBubble;
412 mojo.serviceRegistry.addServiceOverrideForTesting(
413 permissionBubble.WebUsbPermissionBubble.name,
414 pipe => {
415 mockPermissionBubble.bindToPipe(pipe);
416 });
417
418 return fakeUsbDevices().then(fakeDevices => Promise.resolve({
419 DeviceManager: deviceManager.DeviceManager,
420 Device: device.Device,
421 mockDeviceManager: mockDeviceManager,
422 mockPermissionBubble: mockPermissionBubble,
423 fakeDevices: fakeDevices,
424 assertDeviceInfoEquals: assertDeviceInfoEquals,
425 assertConfigurationInfoEquals: assertConfigurationInfoEquals,
426 }));
427 });
428 }
429
430 function usb_test(func, name, properties) {
431 mojo_test(mojo => usbMocks(mojo).then(usb => {
432 let result = Promise.resolve(func(usb));
433 let cleanUp = () => usb.mockDeviceManager.reset();
434 result.then(cleanUp, cleanUp);
435 return result;
436 }), name, properties);
437 }
OLDNEW
« no previous file with comments | « third_party/WebKit/LayoutTests/usb/resources/fake-devices.js ('k') | third_party/WebKit/LayoutTests/usb/usb.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698