@substrat-run/contract-tests 0.126.0 → 0.127.0

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.
@@ -1 +1 @@
1
- {"version":3,"file":"scope-host-suite.d.ts","sourceRoot":"","sources":["../src/scope-host-suite.ts"],"names":[],"mappings":"AAEA,OAAO,EAkBL,KAAK,SAAS,EAUf,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAOL,KAAK,SAAS,EACf,MAAM,sBAAsB,CAAC;AAW9B,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,SAAS,CAAC;IAChB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AA2BD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,aAAa,MACrB,OAAO,CAAC,OAAO,CAAC,QACb,SAAS,YACL,MAAM,KACf,OAAO,CAAC,IAAI,CAOd,CAAC;AAEF,iFAAiF;AACjF,MAAM,WAAW,qBAAqB;IACpC;;;;;;OAMG;IACH,2BAA2B,CAAC,EAAE,OAAO,CAAC;CACvC;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,OAAO,CAAC,gBAAgB,CAAC,EAC5C,IAAI,GAAE,qBAA0B,GAC/B,IAAI,CA0/ON"}
1
+ {"version":3,"file":"scope-host-suite.d.ts","sourceRoot":"","sources":["../src/scope-host-suite.ts"],"names":[],"mappings":"AAEA,OAAO,EAkBL,KAAK,SAAS,EAUf,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAOL,KAAK,SAAS,EACf,MAAM,sBAAsB,CAAC;AAW9B,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,SAAS,CAAC;IAChB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AA2BD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,aAAa,MACrB,OAAO,CAAC,OAAO,CAAC,QACb,SAAS,YACL,MAAM,KACf,OAAO,CAAC,IAAI,CAOd,CAAC;AAEF,iFAAiF;AACjF,MAAM,WAAW,qBAAqB;IACpC;;;;;;OAMG;IACH,2BAA2B,CAAC,EAAE,OAAO,CAAC;CACvC;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,OAAO,CAAC,gBAAgB,CAAC,EAC5C,IAAI,GAAE,qBAA0B,GAC/B,IAAI,CA6jPN"}
@@ -5316,9 +5316,12 @@ export function scopeHostContractSuite(adapterName, makeFixture, opts = {}) {
5316
5316
  await move(folder('f1'), folder('fr'), folder('f3'));
5317
5317
  });
5318
5318
  it('terminates on a graph that is already cyclic', async () => {
5319
- // `link` does not refuse a cycle (a follow-up), so one can exist: c1 ⇄ c2.
5320
- await link(folder('c1'), folder('c2'));
5321
- await link(folder('c2'), folder('c1'));
5319
+ // `link` refuses a cycle too now (#1875), so the only way one can exist is a
5320
+ // restored dump — c1 ⇄ c2, planted the same way an undeclared or expired edge is.
5321
+ await plant([
5322
+ { subject: 'folder:c1', object: 'folder:c2' },
5323
+ { subject: 'folder:c2', object: 'folder:c1' },
5324
+ ]);
5322
5325
  await link(folder('cx'), folder('fr'));
5323
5326
  await move(folder('cx'), folder('fr'), folder('c1'));
5324
5327
  expect(await edges(folder('cx'))).toEqual([
@@ -5329,6 +5332,53 @@ export function scopeHostContractSuite(adapterName, makeFixture, opts = {}) {
5329
5332
  await expectRefusal(move(folder('c1'), folder('c2'), folder('cx')), 'validation_failed', /its own ancestor/);
5330
5333
  });
5331
5334
  });
5335
+ /**
5336
+ * #1875: `ctx.link` refuses a cycle the same way `ctx.relink` does, via the same shared
5337
+ * walk (`entity-edges.ts`'s `assertNoCycle`) — a behaviour change to a shipped verb, since
5338
+ * a module that already wrote one (by accident) now fails where it used to succeed.
5339
+ */
5340
+ describe("link refuses a cycle, sharing relink's walk (#1875)", () => {
5341
+ // lr ← l1 ← l2, and a sibling subtree lr ← l3.
5342
+ beforeAll(async () => {
5343
+ await link(folder('l1'), folder('lr'));
5344
+ await link(folder('l2'), folder('l1'));
5345
+ await link(folder('l3'), folder('lr'));
5346
+ });
5347
+ it('refuses linking a parent that is the child itself', async () => {
5348
+ await expectRefusal(link(folder('l1'), folder('l1')), 'validation_failed', /its own ancestor/);
5349
+ expect(await edges(folder('l1'))).toEqual([{ object: 'folder:lr', revoked: false }]);
5350
+ });
5351
+ it('refuses linking into its own descendant', async () => {
5352
+ // lr is an ancestor of l2 (lr ← l1 ← l2); linking lr under l2 would make lr its own
5353
+ // descendant.
5354
+ await expectRefusal(link(folder('lr'), folder('l2')), 'validation_failed', /its own ancestor/);
5355
+ expect(await edges(folder('lr'))).toEqual([]);
5356
+ });
5357
+ it('the twin: a link into a sibling subtree still succeeds', async () => {
5358
+ await link(folder('l2'), folder('l3'));
5359
+ expect(await edges(folder('l2'))).toEqual([
5360
+ { object: 'folder:l1', revoked: false },
5361
+ { object: 'folder:l3', revoked: false },
5362
+ ]);
5363
+ });
5364
+ it('an already-cyclic graph (planted via export/restore) terminates instead of looping', async () => {
5365
+ // `link` refuses a cycle now, so the only way one exists is a restored dump.
5366
+ await plant([
5367
+ { subject: 'folder:lc1', object: 'folder:lc2' },
5368
+ { subject: 'folder:lc2', object: 'folder:lc1' },
5369
+ ]);
5370
+ await link(folder('lc3'), folder('lr'));
5371
+ // lc1's own chain (lc1 → lc2 → lc1 → …) never reaches lc3, so this still succeeds —
5372
+ // the point is that the walk finishes at all instead of hanging on the cycle.
5373
+ await link(folder('lc3'), folder('lc1'));
5374
+ expect(await edges(folder('lc3'))).toEqual([
5375
+ { object: 'folder:lc1', revoked: false },
5376
+ { object: 'folder:lr', revoked: false },
5377
+ ]);
5378
+ // A member of the cycle still refuses becoming its own ancestor.
5379
+ await expectRefusal(link(folder('lc1'), folder('lc1')), 'validation_failed', /its own ancestor/);
5380
+ });
5381
+ });
5332
5382
  it('a tombstone survives export, restore and snapshot — never resurrected', async () => {
5333
5383
  await link(item('rl10'), box('rb1'));
5334
5384
  await move(item('rl10'), box('rb1'), box('rb2'));