Skip to content

Commit

Permalink
Moving shared device list filter helper to utilities.js. Adding unit …
Browse files Browse the repository at this point in the history
…tests for those filters. Adding unit tests and e2e tests to both Cloud List and USB List functionality.
  • Loading branch information
JamesHagerman committed Apr 23, 2020
1 parent 8adf5c0 commit de0b32d
Show file tree
Hide file tree
Showing 8 changed files with 394 additions and 62 deletions.
3 changes: 2 additions & 1 deletion src/cli/usb.js
Expand Up @@ -25,7 +25,8 @@ module.exports = ({ commandProcessor, root }) => {
},
handler: (args) => {
return usbCommand().list(args);
}
},
epilogue: 'Param filter can be: online, offline, a platform name (photon, electron, etc), a device ID or name'
});

// Common options for start-listening, stop-listening, safe-mode, dfu and reset
Expand Down
6 changes: 4 additions & 2 deletions src/cli/usb.test.js
Expand Up @@ -48,19 +48,21 @@ describe('USB Command-Line Interface', () => {
it('Handles `list` command', () => {
const argv = commandProcessor.parse(root, ['usb', 'list']);
expect(argv.clierror).to.equal(undefined);
expect(argv.params).to.eql({});
expect(argv.params).to.eql({ filter: undefined });
});

it('Includes help', () => {
commandProcessor.parse(root, ['usb', 'list', '--help'], termWidth);
commandProcessor.showHelp((helpText) => {
expect(helpText).to.equal([
'List the devices connected to the host computer',
'Usage: particle usb list [options]',
'Usage: particle usb list [options] [filter]',
'',
'Options:',
' --exclude-dfu Do not list devices which are in DFU mode [boolean]',
' --ids-only Print only device IDs [boolean]',
'',
'Param filter can be: online, offline, a platform name (photon, electron, etc), a device ID or name',
''
].join(os.EOL));
});
Expand Down
24 changes: 2 additions & 22 deletions src/cmd/cloud.js
Expand Up @@ -492,31 +492,11 @@ class CloudCommand {


getAllDeviceAttributes(filter) {
const { buildDeviceFilter } = utilities;
const api = new ApiClient();
api.ensureToken();

let filterFunc = null;

if (filter){
const platforms = utilities.knownPlatforms();
if (filter === 'online') {
filterFunc = (d) => {
return d.connected;
};
} else if (filter === 'offline') {
filterFunc = (d) => {
return !d.connected;
};
} else if (Object.keys(platforms).indexOf(filter) >= 0) {
filterFunc = (d) => {
return d.product_id === platforms[filter];
};
} else {
filterFunc = (d) => {
return d.id === filter || d.name === filter;
};
}
}
let filterFunc = buildDeviceFilter(filter);

return Promise.resolve().then(() => {
return api.listDevices();
Expand Down
26 changes: 3 additions & 23 deletions src/cmd/usb.js
@@ -1,5 +1,5 @@
const { spin } = require('../app/ui');
const { asyncMapSeries, knownPlatforms } = require('../lib/utilities');
const { asyncMapSeries, buildDeviceFilter } = require('../lib/utilities');
const { getDevice, formatDeviceInfo } = require('./device-util');
const { getUsbDevices, openUsbDevice, openUsbDeviceById } = require('./usb-util');
const { systemSupportsUdev, udevRulesInstalled, installUdevRules } = require('./udev');
Expand All @@ -18,27 +18,7 @@ module.exports = class UsbCommand {
const excludeDfu = args['exclude-dfu'];
const filter = args.params.filter;

let filterFunc = null;
if (filter){
const platforms = knownPlatforms();
if (filter === 'online') {
filterFunc = (d) => {
return d.connected;
};
} else if (filter === 'offline') {
filterFunc = (d) => {
return !d.connected;
};
} else if (Object.keys(platforms).indexOf(filter) >= 0) {
filterFunc = (d) => {
return d.platform_id === platforms[filter];
};
} else {
filterFunc = (d) => {
return d.id === filter || d.name === filter;
};
}
}
const filterFunc = buildDeviceFilter(filter);

// Enumerate USB devices
return getUsbDevices({ dfuMode: !excludeDfu })
Expand Down Expand Up @@ -99,7 +79,7 @@ module.exports = class UsbCommand {
console.log('No devices found.');
} else {
devices = devices.sort((a, b) => a.name.localeCompare(b.name)); // Sort devices by name

if (filter) {
devices = devices.filter(filterFunc);
}
Expand Down
33 changes: 33 additions & 0 deletions src/lib/utilities.js
Expand Up @@ -351,6 +351,39 @@ module.exports = {
};
},

/**
* Generates a filter function to be used with `Array.filter()` when filtering a list of Devices
* by some value. Supports `online`, `offline`, Platform Name, Device ID, or Device Name
*
* @param {string} filter - Filter value to use for filtering a list of devices
* @returns {function|null}
*/
buildDeviceFilter(filter) {
const { knownPlatforms } = module.exports;
let filterFunc = null;
if (filter){
const platforms = knownPlatforms();
if (filter === 'online') {
filterFunc = (d) => {
return d.connected;
};
} else if (filter === 'offline') {
filterFunc = (d) => {
return !d.connected;
};
} else if (Object.keys(platforms).indexOf(filter) >= 0) {
filterFunc = (d) => {
return d.platform_id === platforms[filter];
};
} else {
filterFunc = (d) => {
return d.id === filter || d.name === filter;
};
}
}
return filterFunc;
},

ensureError(err){
if (!_.isError(err) && !(err instanceof VError)){
return new Error(_.isArray(err) ? err.join('\n') : err);
Expand Down
126 changes: 126 additions & 0 deletions src/lib/utilities.test.js
Expand Up @@ -26,5 +26,131 @@ describe('Utilities', () => {
expect(util.compliment(items, excluded)).to.eql(['bar', 'qux']);
});
});

describe('buildDeviceFilter', () => {
it('returns null if no filter string is provided', () => {
expect(util.buildDeviceFilter()).to.eql(null);
});

describe('Built filter functions', () => {
let deviceList;
beforeEach(() => {
deviceList = [
{
id: 'deadbeef1',
name: 'device-a',
platform_id: 6,
connected: true
},
{
id: 'deadbeef2',
name: 'device-b',
platform_id: 10,
connected: true
},
{
id: 'deadbeef3',
name: 'device-c',
platform_id: 13,
connected: false
}
];
});

it('Filters devices by online', () => {
let filterByOnline = util.buildDeviceFilter('online');

let onlineDevices = deviceList.filter(filterByOnline);

expect(onlineDevices).to.eql([
{
id: 'deadbeef1',
name: 'device-a',
platform_id: 6,
connected: true
},
{
id: 'deadbeef2',
name: 'device-b',
platform_id: 10,
connected: true
}
]);
});

it('Filters devices by offline', () => {
let filterByOffline = util.buildDeviceFilter('offline');

let offlineDevices = deviceList.filter(filterByOffline);

expect(offlineDevices).to.eql([
{
id: 'deadbeef3',
name: 'device-c',
platform_id: 13,
connected: false
}
]);
});

it('Filters devices by platform name', () => {
let electronOnly = util.buildDeviceFilter('electron');
let boronOnly = util.buildDeviceFilter('boron');

let electrons = deviceList.filter(electronOnly);
let borons = deviceList.filter(boronOnly);

expect(electrons).to.eql([
{
id: 'deadbeef2',
name: 'device-b',
platform_id: 10,
connected: true
}
]);

expect(borons).to.eql([
{
id: 'deadbeef3',
name: 'device-c',
platform_id: 13,
connected: false
}
]);
});

it('Filters devices by Device ID', () => {
let filterByName = util.buildDeviceFilter('deadbeef2');

let matchingDevices = deviceList.filter(filterByName);

expect(matchingDevices).to.eql([
{
id: 'deadbeef2',
name: 'device-b',
platform_id: 10,
connected: true
}
]);
});

it('Filters devices by Device Name', () => {
let filterByName = util.buildDeviceFilter('device-a');

let matchingDevices = deviceList.filter(filterByName);

expect(matchingDevices).to.eql([
{
id: 'deadbeef1',
name: 'device-a',
platform_id: 6,
connected: true
},
]);
});


});
});
});

0 comments on commit de0b32d

Please sign in to comment.