packageRoot function

Future<String> packageRoot(
  1. String package
)

The on-disk root of package, resolved through the package config rather than the process working directory.

Directory.current is not a package root — it is wherever the runner was invoked from. A test that anchors on it, or that reaches a sibling package through a '..' join, passes from inside its own package and fails from the repository root, and the failure looks like broken code rather than a broken anchor.

Use it wherever a test needs a real path:

final application = await createApp(basePath: await packageRoot('my_app'));
final fixture = p.join(await packageRoot('my_app'), 'test', 'fixtures');

An application's own tests need this for the same reason the framework's do: Application.configure takes a basePath, and defaulting it to the working directory means views, storage/ and the database move depending on where the process started.

Throws StateError when package is not resolvable — it has to be a dependency of the package under test, or a member of the same workspace.

Implementation

Future<String> packageRoot(String package) async {
  final lib = await Isolate.resolvePackageUri(Uri.parse('package:$package/'));
  if (lib == null) {
    throw StateError(
      'Cannot resolve "package:$package/". It has to be a dependency of the '
      'package under test, or a member of the same workspace, for a test to '
      'locate its files.',
    );
  }
  return p.normalize(p.join(lib.toFilePath(), '..'));
}