Skip to content

Commit

Permalink
feat: expose cpu info (#6)
Browse files Browse the repository at this point in the history
* feat: expose cpu info

* refactor: create cpu info class

* fix: cleanup

* refactor: update class and test description

* refactor: add undefined return type

* refactor: change name of tests

* docs: update README.md

---------

Co-authored-by: evujici <[email protected]>
  • Loading branch information
edvujic and evujici authored May 23, 2024
1 parent 22a3304 commit 6e43d38
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 49 deletions.
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,19 @@ if (BrowserInfo.isChrome() && BrowserInfo.isSubVersionOf('110')) {
}
```

Use the `CpuInfo` class to check certain details about the CPU.

```javascript
import { CpuInfo } from '@webex/web-capabilities';

const logicalCores = CpuInfo.getNumLogicalCores();

if (logicalCores) {
console.log(`Number of logical CPU cores: ${logicalCores}`);
}
```


# Setup

1. Run `yarn` to install dependencies.
Expand Down
15 changes: 7 additions & 8 deletions src/cpu-info.spec.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
import { getCpuInfo } from './cpu-info';
import { CpuInfo } from './cpu-info';

describe('getCpuInfo', () => {
it('should get correct CPU information when available', () => {
describe('CpuInfo', () => {
it('should return the number of logical CPU cores when the information is available', () => {
expect.assertions(1);

jest.spyOn(Navigator.prototype, 'hardwareConcurrency', 'get').mockReturnValue(1);

const cpuInfo = getCpuInfo();
expect(cpuInfo.numLogicalCores).toBe(1);
expect(CpuInfo.getNumLogicalCores()).toBe(1);
});
it('should get correct CPU information when not available', () => {

it('should return undefined when the logical CPU cores information is not available', () => {
expect.assertions(1);

jest.spyOn(Navigator.prototype, 'hardwareConcurrency', 'get').mockImplementation();

const cpuInfo = getCpuInfo();
expect(cpuInfo.numLogicalCores).toBeUndefined();
expect(CpuInfo.getNumLogicalCores()).toBeUndefined();
});
});
23 changes: 9 additions & 14 deletions src/cpu-info.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,13 @@
export type CpuInfo = {
numLogicalCores?: number;
};

/**
* Get the available information about the machine's CPU.
*
* @returns The {@link CpuInfo}.
* A class that provides information about the CPU.
*/
export function getCpuInfo(): CpuInfo {
const cpuInfo = {} as CpuInfo;

if (navigator.hardwareConcurrency) {
cpuInfo.numLogicalCores = navigator.hardwareConcurrency;
export class CpuInfo {
/**
* Gets the number of logical CPU cores.
*
* @returns The number of logical CPU cores, or undefined if not available.
*/
static getNumLogicalCores(): number | undefined {
return navigator.hardwareConcurrency;
}

return cpuInfo;
}
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './browser-info';
export * from './web-capabilities';
export * from './cpu-info';
20 changes: 4 additions & 16 deletions src/web-capabilities.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,47 +6,35 @@ import { CapabilityState, WebCapabilities } from './web-capabilities';
*
* @param cpuInfo - The {@link CpuInfo} to mock.
*/
const mockCpuInfo = (cpuInfo: CpuInfo) => {
// eslint-disable-next-line dot-notation
WebCapabilities['cpuInfo'] = cpuInfo;
};

describe('WebCapabilities', () => {
it('should get correct capabilities for a machine with unknown CPU information', () => {
expect.assertions(4);

mockCpuInfo({});

jest.spyOn(CpuInfo, 'getNumLogicalCores').mockImplementation();
expect(WebCapabilities.isCapableOfBackgroundNoiseRemoval()).toBe(CapabilityState.UNKNOWN);
expect(WebCapabilities.isCapableOfVirtualBackground()).toBe(CapabilityState.UNKNOWN);
expect(WebCapabilities.isCapableOfReceiving1080pVideo()).toBe(CapabilityState.UNKNOWN);
expect(WebCapabilities.isCapableOfSending1080pVideo()).toBe(CapabilityState.UNKNOWN);
});
it('should get correct capabilities for a 1-core machine', () => {
expect.assertions(4);

mockCpuInfo({ numLogicalCores: 1 });

jest.spyOn(CpuInfo, 'getNumLogicalCores').mockReturnValue(1);
expect(WebCapabilities.isCapableOfBackgroundNoiseRemoval()).toBe(CapabilityState.NOT_CAPABLE);
expect(WebCapabilities.isCapableOfVirtualBackground()).toBe(CapabilityState.NOT_CAPABLE);
expect(WebCapabilities.isCapableOfReceiving1080pVideo()).toBe(CapabilityState.NOT_CAPABLE);
expect(WebCapabilities.isCapableOfSending1080pVideo()).toBe(CapabilityState.NOT_CAPABLE);
});
it('should get correct capabilities for a 2-core machine', () => {
expect.assertions(4);

mockCpuInfo({ numLogicalCores: 2 });

jest.spyOn(CpuInfo, 'getNumLogicalCores').mockReturnValue(2);
expect(WebCapabilities.isCapableOfBackgroundNoiseRemoval()).toBe(CapabilityState.CAPABLE);
expect(WebCapabilities.isCapableOfVirtualBackground()).toBe(CapabilityState.CAPABLE);
expect(WebCapabilities.isCapableOfReceiving1080pVideo()).toBe(CapabilityState.CAPABLE);
expect(WebCapabilities.isCapableOfSending1080pVideo()).toBe(CapabilityState.NOT_CAPABLE);
});
it('should get correct capabilities for a 8-core machine', () => {
expect.assertions(4);

mockCpuInfo({ numLogicalCores: 8 });

jest.spyOn(CpuInfo, 'getNumLogicalCores').mockReturnValue(8);
expect(WebCapabilities.isCapableOfBackgroundNoiseRemoval()).toBe(CapabilityState.CAPABLE);
expect(WebCapabilities.isCapableOfVirtualBackground()).toBe(CapabilityState.CAPABLE);
expect(WebCapabilities.isCapableOfReceiving1080pVideo()).toBe(CapabilityState.CAPABLE);
Expand Down
24 changes: 13 additions & 11 deletions src/web-capabilities.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getCpuInfo } from './cpu-info';
import { CpuInfo } from './cpu-info';

/**
* Used by the {@link WebCapabilities} class to mark features as "not capable", "capable", or
Expand All @@ -16,18 +16,17 @@ export enum CapabilityState {
* information.
*/
export class WebCapabilities {
private static cpuInfo = getCpuInfo();

/**
* Checks whether the machine is capable of background noise removal.
*
* @returns A {@link CapabilityState}.
*/
static isCapableOfBackgroundNoiseRemoval(): CapabilityState {
if (WebCapabilities.cpuInfo.numLogicalCores === undefined) {
const numCores = CpuInfo.getNumLogicalCores();
if (numCores === undefined) {
return CapabilityState.UNKNOWN;
}
if (WebCapabilities.cpuInfo.numLogicalCores < 2) {
if (numCores < 2) {
return CapabilityState.NOT_CAPABLE;
}
return CapabilityState.CAPABLE;
Expand All @@ -39,10 +38,11 @@ export class WebCapabilities {
* @returns A {@link CapabilityState}.
*/
static isCapableOfVirtualBackground(): CapabilityState {
if (WebCapabilities.cpuInfo.numLogicalCores === undefined) {
const numCores = CpuInfo.getNumLogicalCores();
if (numCores === undefined) {
return CapabilityState.UNKNOWN;
}
if (WebCapabilities.cpuInfo.numLogicalCores < 2) {
if (numCores < 2) {
return CapabilityState.NOT_CAPABLE;
}
return CapabilityState.CAPABLE;
Expand All @@ -54,10 +54,11 @@ export class WebCapabilities {
* @returns A {@link CapabilityState}.
*/
static isCapableOfReceiving1080pVideo(): CapabilityState {
if (WebCapabilities.cpuInfo.numLogicalCores === undefined) {
const numCores = CpuInfo.getNumLogicalCores();
if (numCores === undefined) {
return CapabilityState.UNKNOWN;
}
if (WebCapabilities.cpuInfo.numLogicalCores < 2) {
if (numCores < 2) {
return CapabilityState.NOT_CAPABLE;
}
return CapabilityState.CAPABLE;
Expand All @@ -69,10 +70,11 @@ export class WebCapabilities {
* @returns A {@link CapabilityState}.
*/
static isCapableOfSending1080pVideo(): CapabilityState {
if (WebCapabilities.cpuInfo.numLogicalCores === undefined) {
const numCores = CpuInfo.getNumLogicalCores();
if (numCores === undefined) {
return CapabilityState.UNKNOWN;
}
if (WebCapabilities.cpuInfo.numLogicalCores < 8) {
if (numCores < 8) {
return CapabilityState.NOT_CAPABLE;
}
return CapabilityState.CAPABLE;
Expand Down

0 comments on commit 6e43d38

Please sign in to comment.