diff options
Diffstat (limited to 'cli/internal/packagemanager/infer_root_test.go')
| -rw-r--r-- | cli/internal/packagemanager/infer_root_test.go | 347 |
1 files changed, 347 insertions, 0 deletions
diff --git a/cli/internal/packagemanager/infer_root_test.go b/cli/internal/packagemanager/infer_root_test.go new file mode 100644 index 0000000..2e37a80 --- /dev/null +++ b/cli/internal/packagemanager/infer_root_test.go @@ -0,0 +1,347 @@ +package packagemanager + +import ( + "reflect" + "testing" + + "github.com/vercel/turbo/cli/internal/turbopath" + "gotest.tools/v3/assert" +) + +func TestInferRoot(t *testing.T) { + type file struct { + path turbopath.AnchoredSystemPath + content []byte + } + + tests := []struct { + name string + fs []file + executionDirectory turbopath.AnchoredSystemPath + rootPath turbopath.AnchoredSystemPath + packageMode PackageType + }{ + // Scenario 0 + { + name: "turbo.json at current dir, no package.json", + fs: []file{ + {path: turbopath.AnchoredUnixPath("turbo.json").ToSystemPath()}, + }, + executionDirectory: turbopath.AnchoredUnixPath("").ToSystemPath(), + rootPath: turbopath.AnchoredUnixPath("").ToSystemPath(), + packageMode: Multi, + }, + { + name: "turbo.json at parent dir, no package.json", + fs: []file{ + {path: turbopath.AnchoredUnixPath("execution/path/subdir/.file").ToSystemPath()}, + {path: turbopath.AnchoredUnixPath("turbo.json").ToSystemPath()}, + }, + executionDirectory: turbopath.AnchoredUnixPath("execution/path/subdir").ToSystemPath(), + // This is "no inference" + rootPath: turbopath.AnchoredUnixPath("execution/path/subdir").ToSystemPath(), + packageMode: Multi, + }, + // Scenario 1A + { + name: "turbo.json at current dir, has package.json, has workspaces key", + fs: []file{ + {path: turbopath.AnchoredUnixPath("turbo.json").ToSystemPath()}, + { + path: turbopath.AnchoredUnixPath("package.json").ToSystemPath(), + content: []byte("{ \"workspaces\": [ \"exists\" ] }"), + }, + }, + executionDirectory: turbopath.AnchoredUnixPath("").ToSystemPath(), + rootPath: turbopath.AnchoredUnixPath("").ToSystemPath(), + packageMode: Multi, + }, + { + name: "turbo.json at parent dir, has package.json, has workspaces key", + fs: []file{ + {path: turbopath.AnchoredUnixPath("execution/path/subdir/.file").ToSystemPath()}, + {path: turbopath.AnchoredUnixPath("turbo.json").ToSystemPath()}, + { + path: turbopath.AnchoredUnixPath("package.json").ToSystemPath(), + content: []byte("{ \"workspaces\": [ \"exists\" ] }"), + }, + }, + executionDirectory: turbopath.AnchoredUnixPath("execution/path/subdir").ToSystemPath(), + rootPath: turbopath.AnchoredUnixPath("").ToSystemPath(), + packageMode: Multi, + }, + { + name: "turbo.json at parent dir, has package.json, has pnpm workspaces", + fs: []file{ + {path: turbopath.AnchoredUnixPath("execution/path/subdir/.file").ToSystemPath()}, + {path: turbopath.AnchoredUnixPath("turbo.json").ToSystemPath()}, + { + path: turbopath.AnchoredUnixPath("package.json").ToSystemPath(), + content: []byte("{}"), + }, + { + path: turbopath.AnchoredUnixPath("pnpm-workspace.yaml").ToSystemPath(), + content: []byte("packages:\n - docs"), + }, + }, + executionDirectory: turbopath.AnchoredUnixPath("execution/path/subdir").ToSystemPath(), + rootPath: turbopath.AnchoredUnixPath("").ToSystemPath(), + packageMode: Multi, + }, + // Scenario 1A aware of the weird thing we do for packages. + { + name: "turbo.json at current dir, has package.json, has packages key", + fs: []file{ + {path: turbopath.AnchoredUnixPath("turbo.json").ToSystemPath()}, + { + path: turbopath.AnchoredUnixPath("package.json").ToSystemPath(), + content: []byte("{ \"packages\": [ \"exists\" ] }"), + }, + }, + executionDirectory: turbopath.AnchoredUnixPath("").ToSystemPath(), + rootPath: turbopath.AnchoredUnixPath("").ToSystemPath(), + packageMode: Single, + }, + { + name: "turbo.json at parent dir, has package.json, has packages key", + fs: []file{ + {path: turbopath.AnchoredUnixPath("execution/path/subdir/.file").ToSystemPath()}, + {path: turbopath.AnchoredUnixPath("turbo.json").ToSystemPath()}, + { + path: turbopath.AnchoredUnixPath("package.json").ToSystemPath(), + content: []byte("{ \"packages\": [ \"exists\" ] }"), + }, + }, + executionDirectory: turbopath.AnchoredUnixPath("execution/path/subdir").ToSystemPath(), + rootPath: turbopath.AnchoredUnixPath("").ToSystemPath(), + packageMode: Single, + }, + // Scenario 1A aware of the the weird thing we do for packages when both methods of specification exist. + { + name: "turbo.json at current dir, has package.json, has workspace and packages key", + fs: []file{ + {path: turbopath.AnchoredUnixPath("turbo.json").ToSystemPath()}, + { + path: turbopath.AnchoredUnixPath("package.json").ToSystemPath(), + content: []byte("{ \"workspaces\": [ \"clobbered\" ], \"packages\": [ \"exists\" ] }"), + }, + }, + executionDirectory: turbopath.AnchoredUnixPath("").ToSystemPath(), + rootPath: turbopath.AnchoredUnixPath("").ToSystemPath(), + packageMode: Multi, + }, + { + name: "turbo.json at parent dir, has package.json, has workspace and packages key", + fs: []file{ + {path: turbopath.AnchoredUnixPath("execution/path/subdir/.file").ToSystemPath()}, + {path: turbopath.AnchoredUnixPath("turbo.json").ToSystemPath()}, + { + path: turbopath.AnchoredUnixPath("package.json").ToSystemPath(), + content: []byte("{ \"workspaces\": [ \"clobbered\" ], \"packages\": [ \"exists\" ] }"), + }, + }, + executionDirectory: turbopath.AnchoredUnixPath("execution/path/subdir").ToSystemPath(), + rootPath: turbopath.AnchoredUnixPath("").ToSystemPath(), + packageMode: Multi, + }, + // Scenario 1B + { + name: "turbo.json at current dir, has package.json, no workspaces", + fs: []file{ + {path: turbopath.AnchoredUnixPath("turbo.json").ToSystemPath()}, + { + path: turbopath.AnchoredUnixPath("package.json").ToSystemPath(), + content: []byte("{}"), + }, + }, + executionDirectory: turbopath.AnchoredUnixPath("").ToSystemPath(), + rootPath: turbopath.AnchoredUnixPath("").ToSystemPath(), + packageMode: Single, + }, + { + name: "turbo.json at parent dir, has package.json, no workspaces", + fs: []file{ + {path: turbopath.AnchoredUnixPath("execution/path/subdir/.file").ToSystemPath()}, + {path: turbopath.AnchoredUnixPath("turbo.json").ToSystemPath()}, + { + path: turbopath.AnchoredUnixPath("package.json").ToSystemPath(), + content: []byte("{}"), + }, + }, + executionDirectory: turbopath.AnchoredUnixPath("execution/path/subdir").ToSystemPath(), + rootPath: turbopath.AnchoredUnixPath("").ToSystemPath(), + packageMode: Single, + }, + { + name: "turbo.json at parent dir, has package.json, no workspaces, includes pnpm", + fs: []file{ + {path: turbopath.AnchoredUnixPath("execution/path/subdir/.file").ToSystemPath()}, + {path: turbopath.AnchoredUnixPath("turbo.json").ToSystemPath()}, + { + path: turbopath.AnchoredUnixPath("package.json").ToSystemPath(), + content: []byte("{}"), + }, + { + path: turbopath.AnchoredUnixPath("pnpm-workspace.yaml").ToSystemPath(), + content: []byte(""), + }, + }, + executionDirectory: turbopath.AnchoredUnixPath("execution/path/subdir").ToSystemPath(), + rootPath: turbopath.AnchoredUnixPath("").ToSystemPath(), + packageMode: Single, + }, + // Scenario 2A + { + name: "no turbo.json, no package.json at current", + fs: []file{}, + executionDirectory: turbopath.AnchoredUnixPath("").ToSystemPath(), + rootPath: turbopath.AnchoredUnixPath("").ToSystemPath(), + packageMode: Multi, + }, + { + name: "no turbo.json, no package.json at parent", + fs: []file{ + {path: turbopath.AnchoredUnixPath("execution/path/subdir/.file").ToSystemPath()}, + }, + executionDirectory: turbopath.AnchoredUnixPath("execution/path/subdir").ToSystemPath(), + rootPath: turbopath.AnchoredUnixPath("execution/path/subdir").ToSystemPath(), + packageMode: Multi, + }, + // Scenario 2B + { + name: "no turbo.json, has package.json with workspaces at current", + fs: []file{ + { + path: turbopath.AnchoredUnixPath("package.json").ToSystemPath(), + content: []byte("{ \"workspaces\": [ \"exists\" ] }"), + }, + }, + executionDirectory: turbopath.AnchoredUnixPath("").ToSystemPath(), + rootPath: turbopath.AnchoredUnixPath("").ToSystemPath(), + packageMode: Multi, + }, + { + name: "no turbo.json, has package.json with workspaces at parent", + fs: []file{ + {path: turbopath.AnchoredUnixPath("execution/path/subdir/.file").ToSystemPath()}, + { + path: turbopath.AnchoredUnixPath("package.json").ToSystemPath(), + content: []byte("{ \"workspaces\": [ \"exists\" ] }"), + }, + }, + executionDirectory: turbopath.AnchoredUnixPath("execution/path/subdir").ToSystemPath(), + rootPath: turbopath.AnchoredUnixPath("execution/path/subdir").ToSystemPath(), + packageMode: Multi, + }, + { + name: "no turbo.json, has package.json with pnpm workspaces at parent", + fs: []file{ + {path: turbopath.AnchoredUnixPath("execution/path/subdir/.file").ToSystemPath()}, + { + path: turbopath.AnchoredUnixPath("package.json").ToSystemPath(), + content: []byte("{ \"workspaces\": [ \"exists\" ] }"), + }, + { + path: turbopath.AnchoredUnixPath("pnpm-workspace.yaml").ToSystemPath(), + content: []byte("packages:\n - docs"), + }, + }, + executionDirectory: turbopath.AnchoredUnixPath("execution/path/subdir").ToSystemPath(), + rootPath: turbopath.AnchoredUnixPath("execution/path/subdir").ToSystemPath(), + packageMode: Multi, + }, + // Scenario 3A + { + name: "no turbo.json, lots of package.json files but no workspaces", + fs: []file{ + { + path: turbopath.AnchoredUnixPath("package.json").ToSystemPath(), + content: []byte("{}"), + }, + { + path: turbopath.AnchoredUnixPath("one/package.json").ToSystemPath(), + content: []byte("{}"), + }, + { + path: turbopath.AnchoredUnixPath("one/two/package.json").ToSystemPath(), + content: []byte("{}"), + }, + { + path: turbopath.AnchoredUnixPath("one/two/three/package.json").ToSystemPath(), + content: []byte("{}"), + }, + }, + executionDirectory: turbopath.AnchoredUnixPath("one/two/three").ToSystemPath(), + rootPath: turbopath.AnchoredUnixPath("one/two/three").ToSystemPath(), + packageMode: Single, + }, + // Scenario 3BI + { + name: "no turbo.json, lots of package.json files, and a workspace at the root that matches execution directory", + fs: []file{ + { + path: turbopath.AnchoredUnixPath("package.json").ToSystemPath(), + content: []byte("{ \"workspaces\": [ \"one/two/three\" ] }"), + }, + { + path: turbopath.AnchoredUnixPath("one/package.json").ToSystemPath(), + content: []byte("{}"), + }, + { + path: turbopath.AnchoredUnixPath("one/two/package.json").ToSystemPath(), + content: []byte("{}"), + }, + { + path: turbopath.AnchoredUnixPath("one/two/three/package.json").ToSystemPath(), + content: []byte("{}"), + }, + }, + executionDirectory: turbopath.AnchoredUnixPath("one/two/three").ToSystemPath(), + rootPath: turbopath.AnchoredUnixPath("one/two/three").ToSystemPath(), + packageMode: Multi, + }, + // Scenario 3BII + { + name: "no turbo.json, lots of package.json files, and a workspace at the root that matches execution directory", + fs: []file{ + { + path: turbopath.AnchoredUnixPath("package.json").ToSystemPath(), + content: []byte("{ \"workspaces\": [ \"does-not-exist\" ] }"), + }, + { + path: turbopath.AnchoredUnixPath("one/package.json").ToSystemPath(), + content: []byte("{}"), + }, + { + path: turbopath.AnchoredUnixPath("one/two/package.json").ToSystemPath(), + content: []byte("{}"), + }, + { + path: turbopath.AnchoredUnixPath("one/two/three/package.json").ToSystemPath(), + content: []byte("{}"), + }, + }, + executionDirectory: turbopath.AnchoredUnixPath("one/two/three").ToSystemPath(), + rootPath: turbopath.AnchoredUnixPath("one/two/three").ToSystemPath(), + packageMode: Single, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + fsRoot := turbopath.AbsoluteSystemPath(t.TempDir()) + for _, file := range tt.fs { + path := file.path.RestoreAnchor(fsRoot) + assert.NilError(t, path.Dir().MkdirAll(0777)) + assert.NilError(t, path.WriteFile(file.content, 0777)) + } + + turboRoot, packageMode := InferRoot(tt.executionDirectory.RestoreAnchor(fsRoot)) + if !reflect.DeepEqual(turboRoot, tt.rootPath.RestoreAnchor(fsRoot)) { + t.Errorf("InferRoot() turboRoot = %v, want %v", turboRoot, tt.rootPath.RestoreAnchor(fsRoot)) + } + if packageMode != tt.packageMode { + t.Errorf("InferRoot() packageMode = %v, want %v", packageMode, tt.packageMode) + } + }) + } +} |
