Add packageBase to simplify how we build packages files and how we process
package import uris

THis is not actively used in the loader unit tests yet, but will be in the
dart2js pipeline.

Change-Id: Ie0db6243c735e2fba396f2a5a156d52ea1e53bbe
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/102125
Reviewed-by: Johnni Winther <johnniwinther@google.com>
diff --git a/pkg/modular_test/lib/src/loader.dart b/pkg/modular_test/lib/src/loader.dart
index 2e6b3ed..8642fd8 100644
--- a/pkg/modular_test/lib/src/loader.dart
+++ b/pkg/modular_test/lib/src/loader.dart
@@ -60,7 +60,9 @@
         var relativeUri = Uri.parse(fileName);
         var isMain = moduleName == 'main';
         var module = Module(moduleName, [], testUri, [relativeUri],
-            mainSource: isMain ? relativeUri : null, isMain: isMain);
+            mainSource: isMain ? relativeUri : null,
+            isMain: isMain,
+            packageBase: Uri.parse('.'));
         if (isMain) mainModule = module;
         modules[moduleName] = module;
       } else if (fileName == '.packages') {
@@ -82,7 +84,8 @@
         return _moduleConflict(moduleName, modules[moduleName], testUri);
       }
       var sources = await _listModuleSources(entryUri);
-      modules[moduleName] = Module(moduleName, [], entryUri, sources);
+      modules[moduleName] = Module(moduleName, [], testUri, sources,
+          packageBase: Uri.parse('$moduleName/'));
     }
   }
   if (spec == null) {
@@ -106,8 +109,9 @@
 Future<List<Uri>> _listModuleSources(Uri root) async {
   List<Uri> sources = [];
   Directory folder = Directory.fromUri(root);
+  int baseUriPrefixLength = folder.parent.uri.path.length;
   await for (var file in folder.list(recursive: true)) {
-    sources.add(Uri.parse(file.uri.path.substring(root.path.length)));
+    sources.add(Uri.parse(file.uri.path.substring(baseUriPrefixLength)));
   }
   return sources..sort((a, b) => a.path.compareTo(b.path));
 }
@@ -156,12 +160,13 @@
       module.isPackage = true;
     } else {
       var packageLibUri = packages[packageName];
+      var rootUri = Directory.fromUri(packageLibUri).parent.uri;
       var sources = await _listModuleSources(packageLibUri);
       // TODO(sigmund): validate that we don't use a different alias for a
       // module that is part of the test (package name and module name should
       // match).
-      modules[packageName] =
-          Module(packageName, [], packageLibUri, sources, isPackage: true);
+      modules[packageName] = Module(packageName, [], rootUri, sources,
+          isPackage: true, packageBase: Uri.parse('lib/'));
     }
   }
 }
@@ -214,7 +219,8 @@
   var isFile = name.endsWith('.dart');
   var entryType = isFile ? 'file' : 'folder';
 
-  var existingIsFile = existing.rootUri == root;
+  var existingIsFile =
+      existing.packageBase.path == './' && existing.sources.length == 1;
   var existingEntryType = existingIsFile ? 'file' : 'folder';
 
   var existingName = existingIsFile
diff --git a/pkg/modular_test/lib/src/suite.dart b/pkg/modular_test/lib/src/suite.dart
index a91c9b3..e5f17a4 100644
--- a/pkg/modular_test/lib/src/suite.dart
+++ b/pkg/modular_test/lib/src/suite.dart
@@ -41,11 +41,18 @@
   /// package name matches the module name.
   bool isPackage;
 
+  /// When [isPackage], the base where all package URIs are resolved against.
+  /// Stored as a relative [Uri] from [rootUri].
+  final Uri packageBase;
+
   /// Whether this is the main entry module of a test.
   bool isMain;
 
   Module(this.name, this.dependencies, this.rootUri, this.sources,
-      {this.mainSource, this.isPackage: false, this.isMain: false}) {
+      {this.mainSource,
+      this.isPackage: false,
+      this.isMain: false,
+      this.packageBase}) {
     if (!_validModuleName.hasMatch(name)) {
       throw ArgumentError("invalid module name: $name");
     }
diff --git a/pkg/modular_test/test/loader/dag/expectation.txt b/pkg/modular_test/test/loader/dag/expectation.txt
index ef49643..885c41f 100644
--- a/pkg/modular_test/test/loader/dag/expectation.txt
+++ b/pkg/modular_test/test/loader/dag/expectation.txt
@@ -18,8 +18,8 @@
 d
   is package? no
   (no dependencies)
-  d.dart
-  e.dart
+  d/d.dart
+  d/e.dart
 
 main
   **main module**
diff --git a/pkg/modular_test/test/loader/dag_with_packages/expectation.txt b/pkg/modular_test/test/loader/dag_with_packages/expectation.txt
index ff6f03a..df35ba5 100644
--- a/pkg/modular_test/test/loader/dag_with_packages/expectation.txt
+++ b/pkg/modular_test/test/loader/dag_with_packages/expectation.txt
@@ -18,8 +18,8 @@
 d
   is package? no
   (no dependencies)
-  d.dart
-  e.dart
+  d/d.dart
+  d/e.dart
 
 main
   **main module**
diff --git a/pkg/modular_test/test/loader/default_package_dependency_error/expectation.txt b/pkg/modular_test/test/loader/default_package_dependency_error/expectation.txt
index 891da78..cf449f3 100644
--- a/pkg/modular_test/test/loader/default_package_dependency_error/expectation.txt
+++ b/pkg/modular_test/test/loader/default_package_dependency_error/expectation.txt
@@ -3,9 +3,9 @@
 expect
   is package? yes
   dependencies: meta
-  expect.dart
-  matchers_lite.dart
-  minitest.dart
+  lib/expect.dart
+  lib/matchers_lite.dart
+  lib/minitest.dart
 
 main
   **main module**
@@ -16,5 +16,5 @@
 meta
   is package? yes
   (no dependencies)
-  dart2js.dart
-  meta.dart
+  lib/dart2js.dart
+  lib/meta.dart
diff --git a/pkg/modular_test/test/loader/tree/expectation.txt b/pkg/modular_test/test/loader/tree/expectation.txt
index ffcf4b0..f438e22 100644
--- a/pkg/modular_test/test/loader/tree/expectation.txt
+++ b/pkg/modular_test/test/loader/tree/expectation.txt
@@ -18,8 +18,8 @@
 d
   is package? no
   (no dependencies)
-  d.dart
-  e.dart
+  d/d.dart
+  d/e.dart
 
 main
   **main module**
diff --git a/pkg/modular_test/test/loader/valid_packages/expectation.txt b/pkg/modular_test/test/loader/valid_packages/expectation.txt
index e549eaa..3c0888d 100644
--- a/pkg/modular_test/test/loader/valid_packages/expectation.txt
+++ b/pkg/modular_test/test/loader/valid_packages/expectation.txt
@@ -3,17 +3,17 @@
 expect
   is package? yes
   dependencies: meta
-  expect.dart
-  matchers_lite.dart
-  minitest.dart
+  lib/expect.dart
+  lib/matchers_lite.dart
+  lib/minitest.dart
 
 js
   is package? yes
   (no dependencies)
-  js.dart
-  js_util.dart
-  src/
-  src/varargs.dart
+  lib/js.dart
+  lib/js_util.dart
+  lib/src/
+  lib/src/varargs.dart
 
 main
   **main module**
@@ -24,5 +24,5 @@
 meta
   is package? yes
   (no dependencies)
-  dart2js.dart
-  meta.dart
+  lib/dart2js.dart
+  lib/meta.dart