about-system 0.10.15 → 0.10.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/about-system-cli.js +1 -1
- package/dist/index.js +1 -1
- package/dist/system-info-api-fNqdECMN.js +2475 -0
- package/dist/system-info-api-fNqdECMN.js.map +1 -0
- package/dist/system-info-api.js +1 -1
- package/package.json +1 -1
- package/src/about-system-cli.test.ts +509 -0
- package/src/info/hardware-bench.test.ts +220 -0
- package/src/info/hardware-probes.test.ts +208 -0
- package/src/info/hardware.ts +1 -1
- package/src/info/memory.test.ts +347 -0
- package/src/info/network.test.ts +174 -0
- package/src/info/platform-os.test.ts +121 -0
- package/src/info/process.test.ts +112 -0
- package/src/info/process.ts +1 -1
- package/src/info/settings.test.ts +105 -0
- package/src/info/software.test.ts +157 -0
- package/src/info/software.ts +1 -1
- package/src/info/system-status.test.ts +207 -0
- package/dist/system-info-api-7iy1ZV2o.js +0 -2475
- package/dist/system-info-api-7iy1ZV2o.js.map +0 -1
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview The four Geekbench lookups share a table format
|
|
3
|
+
* (`[name, score, rank][]`) and a fuzzy matcher, so they're driven here with a
|
|
4
|
+
* small fixture rather than the multi-megabyte real tables.
|
|
5
|
+
*/
|
|
6
|
+
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
7
|
+
|
|
8
|
+
vi.mock("../utils/platform", () => ({ IS_LINUX: true, IS_MAC: false, IS_WINDOWS: false }));
|
|
9
|
+
|
|
10
|
+
const execCommand = vi.hoisted(() => vi.fn());
|
|
11
|
+
vi.mock("../utils/command", () => ({ execCommand, commandExists: vi.fn() }));
|
|
12
|
+
|
|
13
|
+
const files = vi.hoisted(() => ({
|
|
14
|
+
existing: new Set<string>(),
|
|
15
|
+
data: {} as Record<string, string>,
|
|
16
|
+
}));
|
|
17
|
+
const fsMock = vi.hoisted(() => ({
|
|
18
|
+
existsSync: vi.fn((p: string) => files.existing.has(p)),
|
|
19
|
+
readFileSync: vi.fn((p: string) => {
|
|
20
|
+
if (!(p in files.data)) throw new Error("ENOENT");
|
|
21
|
+
return files.data[p];
|
|
22
|
+
}),
|
|
23
|
+
writeFileSync: vi.fn(),
|
|
24
|
+
}));
|
|
25
|
+
vi.mock("fs", () => ({ ...fsMock, default: fsMock }));
|
|
26
|
+
|
|
27
|
+
vi.mock("os", () => {
|
|
28
|
+
const api = { tmpdir: () => "/tmp", cpus: () => [], platform: () => "linux" };
|
|
29
|
+
return { ...api, default: api };
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
const h = await import("./hardware");
|
|
33
|
+
import type { InfoContext } from "../types/internal-types";
|
|
34
|
+
|
|
35
|
+
const CPU_TABLE = {
|
|
36
|
+
scores: [
|
|
37
|
+
["AMD Ryzen 9 7950X", 3000, 1],
|
|
38
|
+
["Intel Core i9-13900K", 2900, 2],
|
|
39
|
+
["Apple M2 Pro", 2700, 3],
|
|
40
|
+
["Qualcomm Snapdragon X Elite", 2500, 4],
|
|
41
|
+
["AMD EPYC 7763", 2400, 5],
|
|
42
|
+
["Mystery Chip 9000", 1000, 6],
|
|
43
|
+
],
|
|
44
|
+
};
|
|
45
|
+
const GPU_TABLE = {
|
|
46
|
+
scores: [
|
|
47
|
+
["NVIDIA GeForce RTX 4090", 300000, 1],
|
|
48
|
+
["AMD Radeon RX 7900 XTX", 200000, 2],
|
|
49
|
+
["Intel Arc A770", 100000, 3],
|
|
50
|
+
["Obscure Accelerator", 50000, 4],
|
|
51
|
+
],
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const ctx = (cache: InfoContext["cache"] = {}): InfoContext => ({ cache });
|
|
55
|
+
|
|
56
|
+
/** Make `cpu()`/`gpu()` resolve to a name via the (mocked) shell tools. */
|
|
57
|
+
const resolveCpu = (name: string) =>
|
|
58
|
+
execCommand.mockImplementation((c: string) => (c === "lscpu" ? `Model name: ${name}` : ""));
|
|
59
|
+
const resolveGpu = (name: string) =>
|
|
60
|
+
execCommand.mockImplementation((c: string) =>
|
|
61
|
+
c === "lspci" ? `01:00.0 VGA compatible controller: NVIDIA [${name}]` : "",
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
beforeEach(() => {
|
|
65
|
+
files.existing = new Set(["cpu-geekbench.json", "gpu-geekbench.json"]);
|
|
66
|
+
files.data = {
|
|
67
|
+
"cpu-geekbench.json": JSON.stringify(CPU_TABLE),
|
|
68
|
+
"gpu-geekbench.json": JSON.stringify(GPU_TABLE),
|
|
69
|
+
};
|
|
70
|
+
execCommand.mockReset().mockReturnValue("");
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
describe("bench (CPU)", () => {
|
|
74
|
+
it("formats score, rank and percentile for the fuzzy-matched CPU", () => {
|
|
75
|
+
resolveCpu("AMD Ryzen 9 7950X");
|
|
76
|
+
expect(h.bench(ctx())).toBe("3k #1 Top 1%");
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it("is empty with no CPU name or no fuzzy match", () => {
|
|
80
|
+
expect(h.bench(ctx())).toBe("");
|
|
81
|
+
resolveCpu("zzzzzzzzzzzz qqqqqqqq");
|
|
82
|
+
expect(h.bench(ctx())).toBe("");
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it("is empty when the benchmark file is unreadable or malformed", () => {
|
|
86
|
+
resolveCpu("AMD Ryzen 9 7950X");
|
|
87
|
+
files.data["cpu-geekbench.json"] = "{not json";
|
|
88
|
+
expect(h.bench(ctx())).toBe("");
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it("finds the table under src/bench or ./bench when not in the cwd", () => {
|
|
92
|
+
resolveCpu("AMD Ryzen 9 7950X");
|
|
93
|
+
files.existing = new Set(["src/bench/cpu-geekbench.json"]);
|
|
94
|
+
files.data = { "src/bench/cpu-geekbench.json": JSON.stringify(CPU_TABLE) };
|
|
95
|
+
expect(h.bench(ctx())).toBe("3k #1 Top 1%");
|
|
96
|
+
|
|
97
|
+
files.existing = new Set(["./bench/cpu-geekbench.json"]);
|
|
98
|
+
files.data = { "./bench/cpu-geekbench.json": JSON.stringify(CPU_TABLE) };
|
|
99
|
+
expect(h.bench(ctx())).toBe("3k #1 Top 1%");
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it("falls back to the module-relative path when no known location exists", () => {
|
|
103
|
+
resolveCpu("AMD Ryzen 9 7950X");
|
|
104
|
+
files.existing = new Set();
|
|
105
|
+
files.data = {};
|
|
106
|
+
// Nothing readable anywhere → swallowed, cached as empty.
|
|
107
|
+
expect(h.bench(ctx())).toBe("");
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it("serves from the cache", () => {
|
|
111
|
+
const c = ctx({ bench: { value: "cached", timestamp: Date.now() } });
|
|
112
|
+
expect(h.bench(c)).toBe("cached");
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
describe("cpu_bench_info", () => {
|
|
117
|
+
it.each([
|
|
118
|
+
["AMD Ryzen 9 7950X", "Geekbench 6: 3k (Rank #1, Top 1%) - AMD"],
|
|
119
|
+
["Intel Core i9-13900K", "Geekbench 6: 3k (Rank #2, Top 17%) - Intel"],
|
|
120
|
+
["Apple M2 Pro", "Geekbench 6: 3k (Rank #3, Top 34%) - ARM"],
|
|
121
|
+
["Qualcomm Snapdragon X Elite", "Geekbench 6: 3k (Rank #4, Top 50%) - ARM"],
|
|
122
|
+
["AMD EPYC 7763", "Geekbench 6: 2k (Rank #5, Top 67%) - AMD"],
|
|
123
|
+
["Mystery Chip 9000", "Geekbench 6: 1k (Rank #6, Top 84%) - Unknown"],
|
|
124
|
+
])("labels %s with its architecture", (name, expected) => {
|
|
125
|
+
resolveCpu(name);
|
|
126
|
+
expect(h.cpu_bench_info(ctx())).toBe(expected);
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
it("is empty with no CPU, no match, or a bad table; and serves cache", () => {
|
|
130
|
+
expect(h.cpu_bench_info(ctx())).toBe("");
|
|
131
|
+
resolveCpu("zzzzzzzzzzzz qqqqqqqq");
|
|
132
|
+
expect(h.cpu_bench_info(ctx())).toBe("");
|
|
133
|
+
resolveCpu("AMD Ryzen 9 7950X");
|
|
134
|
+
files.data["cpu-geekbench.json"] = "oops";
|
|
135
|
+
expect(h.cpu_bench_info(ctx())).toBe("");
|
|
136
|
+
expect(
|
|
137
|
+
h.cpu_bench_info(ctx({ cpu_bench_info: { value: "cached", timestamp: Date.now() } })),
|
|
138
|
+
).toBe("cached");
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
it("locates the table at the alternate paths", () => {
|
|
142
|
+
resolveCpu("AMD Ryzen 9 7950X");
|
|
143
|
+
files.existing = new Set(["src/bench/cpu-geekbench.json"]);
|
|
144
|
+
files.data = { "src/bench/cpu-geekbench.json": JSON.stringify(CPU_TABLE) };
|
|
145
|
+
expect(h.cpu_bench_info(ctx())).toContain("AMD");
|
|
146
|
+
files.existing = new Set(["./bench/cpu-geekbench.json"]);
|
|
147
|
+
files.data = { "./bench/cpu-geekbench.json": JSON.stringify(CPU_TABLE) };
|
|
148
|
+
expect(h.cpu_bench_info(ctx())).toContain("AMD");
|
|
149
|
+
files.existing = new Set();
|
|
150
|
+
files.data = {};
|
|
151
|
+
expect(h.cpu_bench_info(ctx())).toBe("");
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
describe("gpu_bench", () => {
|
|
156
|
+
it("formats the fuzzy-matched GPU", () => {
|
|
157
|
+
resolveGpu("GeForce RTX 4090");
|
|
158
|
+
expect(h.gpu_bench(ctx())).toBe("300k #1 Top 1%");
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
it("is empty with no GPU, no match, or a bad table; serves cache", () => {
|
|
162
|
+
expect(h.gpu_bench(ctx())).toBe("");
|
|
163
|
+
resolveGpu("zzzzzzzzzzzz qqqqqqqq");
|
|
164
|
+
expect(h.gpu_bench(ctx())).toBe("");
|
|
165
|
+
resolveGpu("GeForce RTX 4090");
|
|
166
|
+
files.data["gpu-geekbench.json"] = "oops";
|
|
167
|
+
expect(h.gpu_bench(ctx())).toBe("");
|
|
168
|
+
expect(h.gpu_bench(ctx({ gpu_bench: { value: "c", timestamp: Date.now() } }))).toBe("c");
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
it("locates the table at the alternate paths", () => {
|
|
172
|
+
resolveGpu("GeForce RTX 4090");
|
|
173
|
+
files.existing = new Set(["src/bench/gpu-geekbench.json"]);
|
|
174
|
+
files.data = { "src/bench/gpu-geekbench.json": JSON.stringify(GPU_TABLE) };
|
|
175
|
+
expect(h.gpu_bench(ctx())).toBe("300k #1 Top 1%");
|
|
176
|
+
files.existing = new Set(["./bench/gpu-geekbench.json"]);
|
|
177
|
+
files.data = { "./bench/gpu-geekbench.json": JSON.stringify(GPU_TABLE) };
|
|
178
|
+
expect(h.gpu_bench(ctx())).toBe("300k #1 Top 1%");
|
|
179
|
+
files.existing = new Set();
|
|
180
|
+
files.data = {};
|
|
181
|
+
expect(h.gpu_bench(ctx())).toBe("");
|
|
182
|
+
});
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
describe("gpu_bench_info", () => {
|
|
186
|
+
it.each([
|
|
187
|
+
["GeForce RTX 4090", "Geekbench 6: 300k (Rank #1, Top 1%) - NVIDIA"],
|
|
188
|
+
["Radeon RX 7900 XTX", "Geekbench 6: 200k (Rank #2, Top 25%) - AMD"],
|
|
189
|
+
["Intel Arc A770", "Geekbench 6: 100k (Rank #3, Top 50%) - Intel"],
|
|
190
|
+
["Obscure Accelerator", "Geekbench 6: 50k (Rank #4, Top 75%) - Unknown"],
|
|
191
|
+
])("labels %s with its vendor", (name, expected) => {
|
|
192
|
+
resolveGpu(name);
|
|
193
|
+
expect(h.gpu_bench_info(ctx())).toBe(expected);
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
it("is empty with no GPU, no match, or a bad table; serves cache", () => {
|
|
197
|
+
expect(h.gpu_bench_info(ctx())).toBe("");
|
|
198
|
+
resolveGpu("zzzzzzzzzzzz qqqqqqqq");
|
|
199
|
+
expect(h.gpu_bench_info(ctx())).toBe("");
|
|
200
|
+
resolveGpu("GeForce RTX 4090");
|
|
201
|
+
files.data["gpu-geekbench.json"] = "oops";
|
|
202
|
+
expect(h.gpu_bench_info(ctx())).toBe("");
|
|
203
|
+
expect(
|
|
204
|
+
h.gpu_bench_info(ctx({ gpu_bench_info: { value: "c", timestamp: Date.now() } })),
|
|
205
|
+
).toBe("c");
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
it("locates the table at the alternate paths", () => {
|
|
209
|
+
resolveGpu("GeForce RTX 4090");
|
|
210
|
+
files.existing = new Set(["src/bench/gpu-geekbench.json"]);
|
|
211
|
+
files.data = { "src/bench/gpu-geekbench.json": JSON.stringify(GPU_TABLE) };
|
|
212
|
+
expect(h.gpu_bench_info(ctx())).toContain("NVIDIA");
|
|
213
|
+
files.existing = new Set(["./bench/gpu-geekbench.json"]);
|
|
214
|
+
files.data = { "./bench/gpu-geekbench.json": JSON.stringify(GPU_TABLE) };
|
|
215
|
+
expect(h.gpu_bench_info(ctx())).toContain("NVIDIA");
|
|
216
|
+
files.existing = new Set();
|
|
217
|
+
files.data = {};
|
|
218
|
+
expect(h.gpu_bench_info(ctx())).toBe("");
|
|
219
|
+
});
|
|
220
|
+
});
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
|
+
|
|
3
|
+
const flags = vi.hoisted(() => ({ linux: true, mac: false, windows: false }));
|
|
4
|
+
vi.mock("../utils/platform", () => ({
|
|
5
|
+
get IS_LINUX() {
|
|
6
|
+
return flags.linux;
|
|
7
|
+
},
|
|
8
|
+
get IS_MAC() {
|
|
9
|
+
return flags.mac;
|
|
10
|
+
},
|
|
11
|
+
get IS_WINDOWS() {
|
|
12
|
+
return flags.windows;
|
|
13
|
+
},
|
|
14
|
+
}));
|
|
15
|
+
|
|
16
|
+
const execCommand = vi.hoisted(() => vi.fn());
|
|
17
|
+
vi.mock("../utils/command", () => ({ execCommand, commandExists: vi.fn() }));
|
|
18
|
+
|
|
19
|
+
const fsMock = vi.hoisted(() => ({
|
|
20
|
+
existsSync: vi.fn(() => false),
|
|
21
|
+
readFileSync: vi.fn(() => ""),
|
|
22
|
+
writeFileSync: vi.fn(),
|
|
23
|
+
}));
|
|
24
|
+
vi.mock("fs", () => ({ ...fsMock, default: fsMock }));
|
|
25
|
+
|
|
26
|
+
const osMock = vi.hoisted(() => ({
|
|
27
|
+
cpus: vi.fn(() => [] as { model: string }[]),
|
|
28
|
+
tmpdir: vi.fn(() => "/tmp"),
|
|
29
|
+
platform: vi.fn(() => "linux"),
|
|
30
|
+
}));
|
|
31
|
+
vi.mock("os", () => ({ ...osMock, default: osMock }));
|
|
32
|
+
|
|
33
|
+
const h = await import("./hardware");
|
|
34
|
+
import type { InfoContext } from "../types/internal-types";
|
|
35
|
+
|
|
36
|
+
const ctx = (): InfoContext => ({ cache: {} });
|
|
37
|
+
const platform = (k: "linux" | "mac" | "windows" | "other") => {
|
|
38
|
+
flags.linux = k === "linux";
|
|
39
|
+
flags.mac = k === "mac";
|
|
40
|
+
flags.windows = k === "windows";
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
beforeEach(() => {
|
|
44
|
+
platform("linux");
|
|
45
|
+
execCommand.mockReset().mockReturnValue("");
|
|
46
|
+
fsMock.readFileSync.mockReset().mockReturnValue("");
|
|
47
|
+
osMock.cpus.mockReset().mockReturnValue([]);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
afterEach(() => {
|
|
51
|
+
delete process.env.DISPLAY;
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
describe("cpu", () => {
|
|
55
|
+
it("reads the model from lscpu on Linux and trims `with ...` suffixes", () => {
|
|
56
|
+
execCommand.mockReturnValue("Architecture: x86_64\nModel name: AMD Ryzen 7 5800X with Radeon\nFlags: a");
|
|
57
|
+
expect(h.cpu(ctx())).toBe("AMD Ryzen 7 5800X");
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it("stops the lscpu model at a comma", () => {
|
|
61
|
+
execCommand.mockReturnValue("Model name: Intel(R) Core(TM) i7, 8 cores");
|
|
62
|
+
expect(h.cpu(ctx())).toBe("Intel(R) Core(TM) i7");
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it("falls back to /proc/cpuinfo model name, then Hardware", () => {
|
|
66
|
+
fsMock.readFileSync.mockReturnValue("processor : 0\nmodel name : Fancy CPU\n");
|
|
67
|
+
expect(h.cpu(ctx())).toBe("Fancy CPU");
|
|
68
|
+
fsMock.readFileSync.mockReturnValue("Hardware : BCM2711\n");
|
|
69
|
+
expect(h.cpu(ctx())).toBe("BCM2711");
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it("is empty when Linux offers no CPU name", () => {
|
|
73
|
+
fsMock.readFileSync.mockImplementation(() => {
|
|
74
|
+
throw new Error("x");
|
|
75
|
+
});
|
|
76
|
+
expect(h.cpu(ctx())).toBe("");
|
|
77
|
+
fsMock.readFileSync.mockReturnValue("nothing useful");
|
|
78
|
+
expect(h.cpu(ctx())).toBe("");
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it("uses wmic on Windows, then PowerShell", () => {
|
|
82
|
+
platform("windows");
|
|
83
|
+
execCommand.mockReturnValue("Name=Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz\r\n");
|
|
84
|
+
expect(h.cpu(ctx())).toBe("Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz");
|
|
85
|
+
execCommand.mockImplementation((c: string) => (c.startsWith("wmic") ? "" : "Ryzen 5 3600\r\n"));
|
|
86
|
+
expect(h.cpu(ctx())).toBe("Ryzen 5 3600");
|
|
87
|
+
execCommand.mockReturnValue("");
|
|
88
|
+
expect(h.cpu(ctx())).toBe("");
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it("uses os.cpus elsewhere (macOS)", () => {
|
|
92
|
+
platform("mac");
|
|
93
|
+
osMock.cpus.mockReturnValue([{ model: "Apple M2\r\nPro " }]);
|
|
94
|
+
expect(h.cpu(ctx())).toBe("Apple M2 Pro");
|
|
95
|
+
osMock.cpus.mockReturnValue([]);
|
|
96
|
+
expect(h.cpu(ctx())).toBe("");
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it("serves from the cache", () => {
|
|
100
|
+
const c = ctx();
|
|
101
|
+
execCommand.mockReturnValue("Model name: Cached CPU");
|
|
102
|
+
h.cpu(c);
|
|
103
|
+
execCommand.mockReturnValue("Model name: Other");
|
|
104
|
+
expect(h.cpu(c)).toBe("Cached CPU");
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
describe("gpu", () => {
|
|
109
|
+
it("lists display-class lspci devices using the bracketed marketing name", () => {
|
|
110
|
+
execCommand.mockReturnValue(
|
|
111
|
+
[
|
|
112
|
+
"00:02.0 VGA compatible controller: Intel Corporation UHD Graphics 630 [UHD Graphics 630]",
|
|
113
|
+
"01:00.0 VGA compatible controller: NVIDIA Corporation GA104 [GeForce RTX 3070] (rev a1)",
|
|
114
|
+
"01:00.1 Audio device: NVIDIA Corporation GA104 High Definition Audio",
|
|
115
|
+
"02:00.0 Ethernet controller: Realtek",
|
|
116
|
+
"03:00.0 3D controller: NVIDIA Corporation GA104 [GeForce RTX 3070]",
|
|
117
|
+
].join("\n"),
|
|
118
|
+
);
|
|
119
|
+
expect(h.gpu(ctx())).toBe("UHD Graphics 630, GeForce RTX 3070");
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
it("strips the class prefix and revision when there are no brackets", () => {
|
|
123
|
+
execCommand.mockReturnValue("00:02.0 VGA compatible controller: Intel Corporation HD Graphics (rev 09)");
|
|
124
|
+
expect(h.gpu(ctx())).toBe("Intel Corporation HD Graphics");
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
it("is empty when no GPU is found, or lspci fails", () => {
|
|
128
|
+
execCommand.mockReturnValue("00:1f.0 ISA bridge: Intel");
|
|
129
|
+
expect(h.gpu(ctx())).toBe("");
|
|
130
|
+
execCommand.mockImplementation(() => {
|
|
131
|
+
throw new Error("x");
|
|
132
|
+
});
|
|
133
|
+
expect(h.gpu(ctx())).toBe("");
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
it("lists wmic adapters on Windows, ignoring Microsoft Basic", () => {
|
|
137
|
+
platform("windows");
|
|
138
|
+
execCommand.mockReturnValue("Name=NVIDIA GeForce RTX 4090\r\nName=Microsoft Basic Display Adapter\r\nName=Intel UHD\r\n");
|
|
139
|
+
expect(h.gpu(ctx())).toBe("NVIDIA GeForce RTX 4090, Intel UHD");
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
it("falls back to PowerShell on Windows", () => {
|
|
143
|
+
platform("windows");
|
|
144
|
+
execCommand.mockImplementation((c: string) =>
|
|
145
|
+
c.startsWith("wmic") ? "" : "AMD Radeon RX 7900\r\nMicrosoft Basic Render\r\n\r\n",
|
|
146
|
+
);
|
|
147
|
+
expect(h.gpu(ctx())).toBe("AMD Radeon RX 7900");
|
|
148
|
+
execCommand.mockReturnValue("");
|
|
149
|
+
expect(h.gpu(ctx())).toBe("");
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
it("lists chipset models on macOS", () => {
|
|
153
|
+
platform("mac");
|
|
154
|
+
execCommand.mockReturnValue("Graphics:\n Chipset Model: Apple M2 Pro\n Chipset Model: AMD Radeon Pro");
|
|
155
|
+
expect(h.gpu(ctx())).toBe("Apple M2 Pro, AMD Radeon Pro");
|
|
156
|
+
execCommand.mockReturnValue("none");
|
|
157
|
+
expect(h.gpu(ctx())).toBe("");
|
|
158
|
+
execCommand.mockImplementation(() => {
|
|
159
|
+
throw new Error("x");
|
|
160
|
+
});
|
|
161
|
+
expect(h.gpu(ctx())).toBe("");
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
it("is empty on unknown platforms and serves from the cache", () => {
|
|
165
|
+
platform("other");
|
|
166
|
+
const c = ctx();
|
|
167
|
+
expect(h.gpu(c)).toBe("");
|
|
168
|
+
platform("linux");
|
|
169
|
+
execCommand.mockReturnValue("00:02.0 VGA compatible controller: Intel UHD Graphics [UHD]");
|
|
170
|
+
expect(h.gpu(c)).toBe("");
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
describe("screen_resolution", () => {
|
|
175
|
+
it("parses the xrandr geometry on Linux when DISPLAY is set", () => {
|
|
176
|
+
process.env.DISPLAY = ":0";
|
|
177
|
+
execCommand.mockReturnValue("Screen 0: minimum 8 x 8\nHDMI-1 connected primary 2560x1440+0+0");
|
|
178
|
+
expect(h.screen_resolution()).toBe("2560x1440");
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
it("is empty without DISPLAY, without a match, or when xrandr throws", () => {
|
|
182
|
+
expect(h.screen_resolution()).toBe("");
|
|
183
|
+
process.env.DISPLAY = ":0";
|
|
184
|
+
execCommand.mockReturnValue("nothing");
|
|
185
|
+
expect(h.screen_resolution()).toBe("");
|
|
186
|
+
execCommand.mockImplementation(() => {
|
|
187
|
+
throw new Error("x");
|
|
188
|
+
});
|
|
189
|
+
expect(h.screen_resolution()).toBe("");
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
it("parses the system_profiler resolution on macOS", () => {
|
|
193
|
+
platform("mac");
|
|
194
|
+
execCommand.mockReturnValue("Resolution: 3024 x 1964 Retina");
|
|
195
|
+
expect(h.screen_resolution()).toBe("3024x1964");
|
|
196
|
+
execCommand.mockReturnValue("nope");
|
|
197
|
+
expect(h.screen_resolution()).toBe("");
|
|
198
|
+
execCommand.mockImplementation(() => {
|
|
199
|
+
throw new Error("x");
|
|
200
|
+
});
|
|
201
|
+
expect(h.screen_resolution()).toBe("");
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
it("is empty on other platforms", () => {
|
|
205
|
+
platform("windows");
|
|
206
|
+
expect(h.screen_resolution()).toBe("");
|
|
207
|
+
});
|
|
208
|
+
});
|
package/src/info/hardware.ts
CHANGED
|
@@ -105,7 +105,7 @@ export function cpu(context: InfoContext): string {
|
|
|
105
105
|
return "";
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
-
cpuName = cpuName.trim().replace(/with .*/, "");
|
|
108
|
+
cpuName = cpuName.trim().replace(/with .*/, "").trim();
|
|
109
109
|
|
|
110
110
|
setCachedValue(context.cache, "cpu", cpuName);
|
|
111
111
|
return cpuName;
|