dsh-background-by-model 0.4.3 → 0.4.4
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/README.md +5 -0
- package/README.zh.md +5 -0
- package/lib/client.js +13 -11
- package/lib/client.js.map +1 -1
- package/lib/{host-scan-WjK2VGBe.js → host-scan-B-xmbcxD.js} +9 -9
- package/lib/host-scan.js +1 -1
- package/lib/index.js +1 -1
- package/lib/testing.js +4 -2
- package/package.json +1 -1
- package/test/host-check.test.mjs +108 -34
|
@@ -377,9 +377,9 @@ const HOST_CONTRACTS = [
|
|
|
377
377
|
},
|
|
378
378
|
target: "[data-dockkit-content]",
|
|
379
379
|
checks: [{
|
|
380
|
-
kind: "
|
|
381
|
-
|
|
382
|
-
|
|
380
|
+
kind: "selector",
|
|
381
|
+
selector: "[data-dockkit-content]",
|
|
382
|
+
optionalWhen: "noDockTab"
|
|
383
383
|
}],
|
|
384
384
|
sources: [{
|
|
385
385
|
path: ".",
|
|
@@ -404,9 +404,9 @@ const HOST_CONTRACTS = [
|
|
|
404
404
|
},
|
|
405
405
|
target: "[data-dockkit-empty]",
|
|
406
406
|
checks: [{
|
|
407
|
-
kind: "
|
|
408
|
-
|
|
409
|
-
|
|
407
|
+
kind: "selector",
|
|
408
|
+
selector: "[data-dockkit-empty]",
|
|
409
|
+
optionalWhen: "noDockTab"
|
|
410
410
|
}],
|
|
411
411
|
sources: [{
|
|
412
412
|
path: `${SIDEBAR_RIGHT}/lib/client.js`,
|
|
@@ -430,9 +430,9 @@ const HOST_CONTRACTS = [
|
|
|
430
430
|
},
|
|
431
431
|
target: "[data-dockkit-float]",
|
|
432
432
|
checks: [{
|
|
433
|
-
kind: "
|
|
434
|
-
|
|
435
|
-
|
|
433
|
+
kind: "selector",
|
|
434
|
+
selector: "[data-dockkit-float]",
|
|
435
|
+
optionalWhen: "noFloatPane"
|
|
436
436
|
}],
|
|
437
437
|
sources: [{
|
|
438
438
|
path: `${SIDEBAR_RIGHT}/lib/client.js`,
|
package/lib/host-scan.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as thisPluginDir, c as DSH_FLOOR, i as resolveHostRoots, l as HOST_CONTRACTS, n as listHostPackages, o as versionOf, r as meetsFloor, t as checkHostOnDisk } from "./host-scan-
|
|
1
|
+
import { a as thisPluginDir, c as DSH_FLOOR, i as resolveHostRoots, l as HOST_CONTRACTS, n as listHostPackages, o as versionOf, r as meetsFloor, t as checkHostOnDisk } from "./host-scan-B-xmbcxD.js";
|
|
2
2
|
export { DSH_FLOOR, HOST_CONTRACTS, checkHostOnDisk, listHostPackages, meetsFloor, resolveHostRoots, thisPluginDir, versionOf };
|
package/lib/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as checkHostOnDisk } from "./host-scan-
|
|
1
|
+
import { t as checkHostOnDisk } from "./host-scan-B-xmbcxD.js";
|
|
2
2
|
import { access, mkdir, readFile, readdir, rename, rm, writeFile } from "node:fs/promises";
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
4
|
import { dshHomePath } from "@deepseek-ai/dsh-home-paths";
|
package/lib/testing.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { c as DSH_FLOOR, d as reportToMarkdown, f as symptomOf, i as resolveHostRoots, l as HOST_CONTRACTS, o as versionOf, p as verdictOf, r as meetsFloor, s as CONTRACT_GROUPS, t as checkHostOnDisk, u as labelOf } from "./host-scan-
|
|
1
|
+
import { c as DSH_FLOOR, d as reportToMarkdown, f as symptomOf, i as resolveHostRoots, l as HOST_CONTRACTS, o as versionOf, p as verdictOf, r as meetsFloor, s as CONTRACT_GROUPS, t as checkHostOnDisk, u as labelOf } from "./host-scan-B-xmbcxD.js";
|
|
2
2
|
const UI_CSS = `
|
|
3
3
|
/* The section is rendered INLINE inside the host settings dialog's content
|
|
4
4
|
* column: the host provides the modal chrome (backdrop, centering, closing).
|
|
@@ -297,7 +297,9 @@ const ANCHORS = {
|
|
|
297
297
|
chatNotMounted: "[data-chat-flow],[data-conversation-scroll]",
|
|
298
298
|
trajectoryNotMounted: "[data-conversation-composer-overlay]",
|
|
299
299
|
noRightPanel: "div[data-sidebar-right-panel],[data-dockkit-strip],[data-dockkit-pane]",
|
|
300
|
-
cordisClosed: "[data-cordis-panel]"
|
|
300
|
+
cordisClosed: "[data-cordis-panel]",
|
|
301
|
+
noDockTab: "[data-dockkit-tab]",
|
|
302
|
+
noFloatPane: "[data-dockkit-float],[data-sidebar-right-mode=\"float\"]"
|
|
301
303
|
};
|
|
302
304
|
function mounted(env, anchorId) {
|
|
303
305
|
const sel = ANCHORS[anchorId];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-background-by-model",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.4",
|
|
4
4
|
"description": "Appearance plugin for DeepSeek Harness: an ordered list of model rules, each carrying its own wallpaper, theme color, layout mode, opacity and blur 鈥?the background follows the model you switch to.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"deepseek-harness",
|
package/test/host-check.test.mjs
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The host self-check's own tests
|
|
1
|
+
/**
|
|
2
|
+
* The host self-check's own tests 鈥?run with
|
|
3
3
|
*
|
|
4
4
|
* pnpm test
|
|
5
5
|
*
|
|
6
6
|
* Three things are covered, and they are the three that can rot silently:
|
|
7
7
|
*
|
|
8
|
-
* 1. **The contract table holds together**
|
|
8
|
+
* 1. **The contract table holds together** 鈥?unique ids, machine-checkable
|
|
9
9
|
* sources, a known criticality, and at least one check or an explicit
|
|
10
10
|
* "documentation only" marker. A contract point added without a source would
|
|
11
11
|
* otherwise be invisible to the offline scan.
|
|
12
|
-
* 2. **The probe reports what is actually there**
|
|
12
|
+
* 2. **The probe reports what is actually there** 鈥?the whole probe is driven
|
|
13
13
|
* against a fixture written in the shape of a host DOM, so "the host renamed
|
|
14
14
|
* `--dsw-specific-menu`" produces exactly the failure the panel claims, and a
|
|
15
15
|
* surface that is merely off screen produces `n/a` rather than a false alarm.
|
|
16
|
-
* 3. **The UI stylesheet, and the one piece of version logic**
|
|
16
|
+
* 3. **The UI stylesheet, and the one piece of version logic** 鈥?every `dab-*`
|
|
17
17
|
* class a component uses is defined in it, and the floor comparison is exact
|
|
18
18
|
* on the release triple.
|
|
19
19
|
*
|
|
@@ -36,7 +36,7 @@ const { HOST_CONTRACTS, DSH_FLOOR, probeContracts, verdictOf, meetsFloor, UI_CSS
|
|
|
36
36
|
|
|
37
37
|
const { readFile, readdir } = await import('node:fs/promises')
|
|
38
38
|
|
|
39
|
-
//
|
|
39
|
+
// 鈹€鈹€ 1. the contract table 鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€
|
|
40
40
|
|
|
41
41
|
test('contract ids are unique and non-empty', () => {
|
|
42
42
|
const seen = new Set()
|
|
@@ -75,19 +75,27 @@ test('critical contracts carry a check that can fail', () => {
|
|
|
75
75
|
}
|
|
76
76
|
})
|
|
77
77
|
|
|
78
|
-
//
|
|
78
|
+
// 鈹€鈹€ 2. the probe, against a fixture in the shape of a host DOM 鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€
|
|
79
79
|
|
|
80
80
|
/** A DOM stand-in with just enough selector support for the contract checks. */
|
|
81
81
|
function makeDom(host) {
|
|
82
|
-
/**
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
82
|
+
/**
|
|
83
|
+
* `selector 鈫?present`, including attribute and comma-OR forms. A descendant
|
|
84
|
+
* selector is satisfied when every compound in it is present 鈥?the stand-in has
|
|
85
|
+
* no tree, and the contracts are written so that "the elements exist" is the
|
|
86
|
+
* question being asked.
|
|
87
|
+
*/
|
|
88
|
+
const one = part => {
|
|
89
|
+
// `*` is the universal selector: always satisfied.
|
|
90
|
+
if (part === '*') return true
|
|
91
|
+
if (host.has(part)) return true
|
|
92
|
+
const attr = /^\[([a-z-]+)\]$/.exec(part)
|
|
93
|
+
if (attr !== null && host.has(`[${attr[1]}]`)) return true
|
|
89
94
|
return false
|
|
90
95
|
}
|
|
96
|
+
const matches = sel => sel.split(',').map(p => p.trim()).some(
|
|
97
|
+
part => part.split(/\s+/).every(one),
|
|
98
|
+
)
|
|
91
99
|
return {
|
|
92
100
|
querySelector: sel => (matches(sel) ? { style: {} } : null),
|
|
93
101
|
// Where the host publishes its palette: `body` in the real client, and the
|
|
@@ -96,7 +104,7 @@ function makeDom(host) {
|
|
|
96
104
|
tokenRoot: () => ({ style: {} }),
|
|
97
105
|
// `on` is null for an unscoped token check (the probe reads it off the token
|
|
98
106
|
// root) and the resolved element otherwise. The fixture answers from its own
|
|
99
|
-
// table either way
|
|
107
|
+
// table either way 鈥?whether a value is readable is the host's own business,
|
|
100
108
|
// and that is exactly what the table stands in for.
|
|
101
109
|
computedValue: (token, _on) => (host.get(`computed:${token}`) ?? ''),
|
|
102
110
|
styleSheets: () => [],
|
|
@@ -132,8 +140,8 @@ const PRESENT_TOKENS = [
|
|
|
132
140
|
|
|
133
141
|
/**
|
|
134
142
|
* The literals the HOST's stylesheets declare. The two halves of a token
|
|
135
|
-
* contract ask different questions
|
|
136
|
-
* name", `computed` = "does it resolve to a value"
|
|
143
|
+
* contract ask different questions 鈥?`rule` = "does the host still declare this
|
|
144
|
+
* name", `computed` = "does it resolve to a value" 鈥?so both are listed.
|
|
137
145
|
*/
|
|
138
146
|
const HOST_RULES = [
|
|
139
147
|
'--dsw-menu-surface-fill', '--dsw-specific-menu', '--dsw-specific-sidebar-fill',
|
|
@@ -149,7 +157,7 @@ const OWN_RULES = ['.dab-card']
|
|
|
149
157
|
/**
|
|
150
158
|
* A stylesheet the probe may read.
|
|
151
159
|
*
|
|
152
|
-
* `own: true` writes this plugin's marker
|
|
160
|
+
* `own: true` writes this plugin's marker 鈥?the ONLY thing that tells our sheets
|
|
153
161
|
* apart from the host's, since the host's own CSS modules set `data-plugin` on
|
|
154
162
|
* theirs, so a probe keying off that skips the entire host theme.
|
|
155
163
|
*
|
|
@@ -196,8 +204,27 @@ function hostEnv({ ctx, selectors = CORE_PRESENT, rules = HOST_RULES, tokens = P
|
|
|
196
204
|
return { ...makeDom(host), styleSheets: () => hostStyles(rules), ctx }
|
|
197
205
|
}
|
|
198
206
|
|
|
199
|
-
/**
|
|
200
|
-
|
|
207
|
+
/**
|
|
208
|
+
* The two states the dock alternates between. In the real DOM they live in
|
|
209
|
+
* different panes (a populated tab host carries `data-dockkit-content`, an empty
|
|
210
|
+
* pane carries `data-dockkit-empty`), and each contract's anchor is what says
|
|
211
|
+
* whether its own attribute can be observed 鈥?so the fixture provides the anchor
|
|
212
|
+
* for every contract it expects to answer, and omits the anchors of the ones it
|
|
213
|
+
* expects to read as n/a.
|
|
214
|
+
*/
|
|
215
|
+
const DOCK_POPULATED = [
|
|
216
|
+
'div[data-sidebar-right-panel]',
|
|
217
|
+
'[data-dockkit-tab]',
|
|
218
|
+
'[data-dockkit-content]',
|
|
219
|
+
'[data-dockkit-empty]',
|
|
220
|
+
]
|
|
221
|
+
const DOCK_EMPTY = ['div[data-sidebar-right-panel]', '[data-dockkit-empty]']
|
|
222
|
+
|
|
223
|
+
/** The healthy fixtures: nothing missing, every service published. */
|
|
224
|
+
const healthyEnv = (dock = DOCK_POPULATED) => hostEnv({
|
|
225
|
+
ctx: healthyCtx(),
|
|
226
|
+
selectors: [...CORE_PRESENT, ...dock],
|
|
227
|
+
})
|
|
201
228
|
|
|
202
229
|
/** A context publishing the four services the model hop needs. */
|
|
203
230
|
function healthyCtx(overrides = {}) {
|
|
@@ -211,11 +238,14 @@ function healthyCtx(overrides = {}) {
|
|
|
211
238
|
return { get: id => services[id] }
|
|
212
239
|
}
|
|
213
240
|
|
|
214
|
-
test('a healthy host passes every contract', () => {
|
|
215
|
-
const
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
241
|
+
test('a healthy host passes every contract, in either dock state', () => {
|
|
242
|
+
for (const [name, dock] of [['populated tab', DOCK_POPULATED], ['empty seat', DOCK_EMPTY]]) {
|
|
243
|
+
const results = probeContracts(healthyEnv(dock), 'en')
|
|
244
|
+
const failed = results.filter(r => r.status === 'fail')
|
|
245
|
+
assert.deepEqual(failed.map(r => r.id), [],
|
|
246
|
+
`unexpected failures with a ${name}: ${failed.map(r => `${r.id}: ${r.reason}`).join('; ')}`)
|
|
247
|
+
assert.equal(verdictOf({ results, summary: { pass: results.length, fail: 0, skip: 0, total: results.length } }), 'ok')
|
|
248
|
+
}
|
|
219
249
|
})
|
|
220
250
|
|
|
221
251
|
test('a renamed menu token fails exactly that contract, and names the symptom', () => {
|
|
@@ -232,8 +262,8 @@ test('a renamed menu token fails exactly that contract, and names the symptom',
|
|
|
232
262
|
|
|
233
263
|
test('a renamed token the host still aliases is caught by the rule half', () => {
|
|
234
264
|
// The 0.1.7 menu split in reverse: the host keeps the OLD name working (aliased)
|
|
235
|
-
// but stops declaring the new one. `computed` still answers
|
|
236
|
-
// how that bug stayed silent
|
|
265
|
+
// but stops declaring the new one. `computed` still answers 鈥?which is exactly
|
|
266
|
+
// how that bug stayed silent 鈥?so the `rule` half is the only thing that can
|
|
237
267
|
// tell "renamed" from "still there".
|
|
238
268
|
const env = hostEnv({
|
|
239
269
|
ctx: healthyCtx(),
|
|
@@ -248,7 +278,7 @@ test('a renamed token the host still aliases is caught by the rule half', () =>
|
|
|
248
278
|
|
|
249
279
|
test('a host that stops publishing the palette fails the computed half', () => {
|
|
250
280
|
// The other failure shape: the name is still declared somewhere, but body no
|
|
251
|
-
// longer carries a value
|
|
281
|
+
// longer carries a value 鈥?the case that made 7 healthy tokens look empty when
|
|
252
282
|
// the probe read the wrong element.
|
|
253
283
|
const env = hostEnv({
|
|
254
284
|
ctx: healthyCtx(),
|
|
@@ -270,7 +300,7 @@ test('a dropped session service fails the model hop', () => {
|
|
|
270
300
|
test('the plugin\'s own token stylesheet cannot make a host check pass', () => {
|
|
271
301
|
// The situation that produced the 0.1.7 white band: the plugin re-emits the
|
|
272
302
|
// menu fill itself, so its own sheet declares the token. That re-emission must
|
|
273
|
-
// never be accepted as evidence about the HOST
|
|
303
|
+
// never be accepted as evidence about the HOST 鈥?otherwise the check is green
|
|
274
304
|
// by construction on exactly the host where the token was renamed away.
|
|
275
305
|
const env = hostEnv({
|
|
276
306
|
ctx: healthyCtx(),
|
|
@@ -287,7 +317,7 @@ test('the plugin\'s own token stylesheet cannot make a host check pass', () => {
|
|
|
287
317
|
assert.equal(byId('token.menuSurface').status, 'fail')
|
|
288
318
|
assert.match(byId('token.menuSurface').reason, /no host stylesheet declares/)
|
|
289
319
|
assert.equal(byId('token.menuAlias').status, 'fail')
|
|
290
|
-
//
|
|
320
|
+
// 鈥hile the contract whose other half IS our own sheet still passes: this is
|
|
291
321
|
// what `side: 'own'` is for, and why the two sides must never be merged.
|
|
292
322
|
assert.equal(byId('settings.card').status, 'pass')
|
|
293
323
|
})
|
|
@@ -304,9 +334,53 @@ test('a host sheet carrying data-plugin is not mistaken for ours', () => {
|
|
|
304
334
|
assert.equal(results.find(r => r.id === 'token.bgBase').status, 'pass')
|
|
305
335
|
})
|
|
306
336
|
|
|
337
|
+
test('a closed dock holding only its empty seat is n/a, not a failure', () => {
|
|
338
|
+
// The state a healthy host sits in most of the time: the dock holds no tab, so
|
|
339
|
+
// `data-dockkit-content` (a JS-set attribute the host never styles) cannot be
|
|
340
|
+
// observed at all. It used to read as "no host stylesheet declares it" 鈥?a
|
|
341
|
+
// perfectly healthy host reported as broken.
|
|
342
|
+
const env = healthyEnv(DOCK_EMPTY)
|
|
343
|
+
const results = probeContracts(env, 'en')
|
|
344
|
+
const byId = id => results.find(r => r.id === id)
|
|
345
|
+
assert.equal(byId('dockkit.content').status, 'skip')
|
|
346
|
+
// The empty seat IS on screen here, so its own contract answers.
|
|
347
|
+
assert.equal(byId('dockkit.empty').status, 'pass')
|
|
348
|
+
assert.equal(byId('dockkit.float').status, 'skip')
|
|
349
|
+
assert.deepEqual(results.filter(r => r.status === 'fail').map(r => r.id), [])
|
|
350
|
+
})
|
|
351
|
+
|
|
352
|
+
test('a renamed dock tab attribute still fails once a tab is open', () => {
|
|
353
|
+
// The guard must not swallow a real rename: with a tab open the host has to
|
|
354
|
+
// carry `data-dockkit-content` on the tab host, and if the name moved, say so.
|
|
355
|
+
// A populated tab is on screen (the host marks the tab chip), but the attribute
|
|
356
|
+
// the contract names no longer matches anything.
|
|
357
|
+
const env = hostEnv({
|
|
358
|
+
ctx: healthyCtx(),
|
|
359
|
+
selectors: ['div[data-sidebar-right-panel]', '[data-dockkit-tab]'],
|
|
360
|
+
})
|
|
361
|
+
const results = probeContracts(env, 'en')
|
|
362
|
+
const row = results.find(r => r.id === 'dockkit.content')
|
|
363
|
+
assert.equal(row.status, 'fail')
|
|
364
|
+
assert.match(row.reason, /data-dockkit-content/)
|
|
365
|
+
})
|
|
366
|
+
|
|
367
|
+
test('a floating pane missing its flag is a failure while it is on screen', () => {
|
|
368
|
+
// The float flag is a JS attribute too, so it is only observable when the user
|
|
369
|
+
// has a pane floated 鈥?and then, if the host stopped setting it, the plugin
|
|
370
|
+
// would paint that pane like a docked one.
|
|
371
|
+
const env = hostEnv({
|
|
372
|
+
ctx: healthyCtx(),
|
|
373
|
+
selectors: [...CORE_PRESENT, ...DOCK_POPULATED, '[data-sidebar-right-mode="float"]'],
|
|
374
|
+
})
|
|
375
|
+
const results = probeContracts(env, 'en')
|
|
376
|
+
const row = results.find(r => r.id === 'dockkit.float')
|
|
377
|
+
assert.equal(row.status, 'fail')
|
|
378
|
+
assert.match(row.reason, /data-dockkit-float/)
|
|
379
|
+
})
|
|
380
|
+
|
|
307
381
|
test('a surface that is merely off screen is n/a, not a failure', () => {
|
|
308
382
|
// The app frame and every service are up (the settings section is rendered
|
|
309
|
-
// inside the frame, so the frame is always there)
|
|
383
|
+
// inside the frame, so the frame is always there) 鈥?but the conversation view,
|
|
310
384
|
// the right panel and the Cordis panel are not. Nothing is broken; those
|
|
311
385
|
// surfaces simply are not there to observe.
|
|
312
386
|
const env = hostEnv({
|
|
@@ -326,7 +400,7 @@ test('a surface that is merely off screen is n/a, not a failure', () => {
|
|
|
326
400
|
})
|
|
327
401
|
|
|
328
402
|
test('a mounted but marker-less surface is a failure, not n/a', () => {
|
|
329
|
-
// The dialog is open, so the right panel's anchor is off screen
|
|
403
|
+
// The dialog is open, so the right panel's anchor is off screen 鈥?but the
|
|
330
404
|
// dialog's own selector still matches. A surface whose anchor IS on screen and
|
|
331
405
|
// whose selector is not is a rename, and must not read as "not observable".
|
|
332
406
|
const env = hostEnv({
|
|
@@ -342,7 +416,7 @@ test('a mounted but marker-less surface is a failure, not n/a', () => {
|
|
|
342
416
|
assert.equal(byId('chat.flow').status, 'skip')
|
|
343
417
|
})
|
|
344
418
|
|
|
345
|
-
//
|
|
419
|
+
// 鈹€鈹€ 3. the settings UI's own stylesheet 鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€
|
|
346
420
|
|
|
347
421
|
test('every dab-* class a component uses is defined in the UI stylesheet', async () => {
|
|
348
422
|
const dir = join(pluginDir, 'src', 'client')
|
|
@@ -372,7 +446,7 @@ test('every dab-* class a component uses is defined in the UI stylesheet', async
|
|
|
372
446
|
assert.deepEqual(missing, [], `classes used but never styled: ${missing.map(m => `${m.cls} (${m.file})`).join(', ')}`)
|
|
373
447
|
})
|
|
374
448
|
|
|
375
|
-
//
|
|
449
|
+
// 鈹€鈹€ 4. the floor comparison 鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€鈹€
|
|
376
450
|
|
|
377
451
|
test('the floor comparison is coarse on purpose and exact on the triple', () => {
|
|
378
452
|
assert.equal(meetsFloor('0.1.7-rc.2', DSH_FLOOR), true, 'the floor itself satisfies the floor')
|