passsy / avoid-circular-feature-dependenciesr3
No Circular Feature Dependencies
PublicTwo feature files must not import each other; move the shared concept into something both depend on, or inline it, so each can be read and deleted alone.
tests, run by the registry6 passed · slowest 6.4 ms
- The advice links to wellactually.dev
✓fires6.4 ms
fires when the agent writes an import back to a file that imports this one
write lib/checkout/checkout_controller.dart · in fixtures/shopfired: line 1
import 'package:shop/cart/cart_controller.dart';
class CheckoutController {
void start() => cart.lockForCheckout();
}✓fires4.1 ms
fires on a relative import that closes the cycle
write lib/checkout/checkout_controller.dart · in fixtures/shopfired: line 1
import '../cart/cart_controller.dart';
class CheckoutController {}✓quiet4.2 ms
stays quiet on a one-way import
write lib/checkout/checkout_controller.dart · in fixtures/shopstayed quiet
import 'package:shop/cart/cart_badge.dart';
class CheckoutController {}✓quiet3.6 ms
stays quiet when the import was already there
write lib/checkout/checkout_controller.dart · in fixtures/shop · wrote line 4stayed quiet
import 'package:shop/cart/cart_controller.dart';
class CheckoutController {
void start() => cart.lockForCheckout();
}✓skips0.0 ms
stays quiet when the agent only reads the file
read lib/checkout/checkout_controller.dart · in fixtures/shopno handler of the detector wants this event
import 'package:shop/cart/cart_controller.dart';
class CheckoutController {
void start() => cart.lockForCheckout();
}✓quiet3.6 ms
stays quiet on dart: imports
write lib/checkout/checkout_controller.dart · in fixtures/shopstayed quiet
import 'dart:async';
detector.test.tseach detect() call runs the real detectorEdit
import { expect, test } from "vitest";
import { detect, edit, read, source, write } from "@wellactually/sdk/v3/test";
const shop = { project: "fixtures/shop" };
const checkout = source`
import 'package:shop/cart/cart_controller.dart';
class CheckoutController {
void start() => cart.lockForCheckout();
}
`;
test("fires when the agent writes an import back to a file that imports this one", () => {
expect(detect(write("lib/checkout/checkout_controller.dart", checkout), shop)).toEqual([
{ line: 1 },
]);
});
test("fires on a relative import that closes the cycle", () => {
const code = "import '../cart/cart_controller.dart';\n\nclass CheckoutController {}";
expect(detect(write("lib/checkout/checkout_controller.dart", code), shop)).toEqual([{ line: 1 }]);
});
test("stays quiet on a one-way import", () => {
const code = "import 'package:shop/cart/cart_badge.dart';\n\nclass CheckoutController {}";
expect(detect(write("lib/checkout/checkout_controller.dart", code), shop)).toEqual([]);
});
test("stays quiet when the import was already there", () => {
expect(detect(edit("lib/checkout/checkout_controller.dart", checkout, { written: " void start() => cart.lockForCheckout();" }), shop)).toEqual([]);
});
test("stays quiet when the agent only reads the file", () => {
expect(detect(read("lib/checkout/checkout_controller.dart", checkout), shop)).toEqual([]);
});
test("stays quiet on dart: imports", () => {
expect(detect(write("lib/checkout/checkout_controller.dart", "import 'dart:async';\n"), shop)).toEqual([]);
});