Skip to content

Commit

Permalink
dependency resolving
Browse files Browse the repository at this point in the history
  • Loading branch information
ComradeVanti committed Aug 15, 2024
1 parent beb4af2 commit 2910098
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 99 deletions.
25 changes: 24 additions & 1 deletion test/integration/network.mock.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import nock from "nock";
import { DomainName } from "../../src/domain/domain-name";
import { UnityPackument } from "../../src/domain/packument";
import { RegistryUrl } from "../../src/domain/registry-url";
import { RegistryUrl, unityRegistryUrl } from "../../src/domain/registry-url";
import { SemanticVersion } from "../../src/domain/semantic-version";
import { buildPackument } from "../data-packument";

/**
* Mocks a packument on a remote package registry.
Expand Down Expand Up @@ -49,3 +51,24 @@ export function mockIsOfficialUnityPackage(
) {
mockUnityDocPage(packageName, isOfficial);
}

/**
* Mocks whether a package is built-in.
* @param packageName The package name.
* @param version The package version.
* @param isBuiltIn Whether the package is built-in or not.
*/
export function mockIsBuiltInPackage(
packageName: DomainName,
version: SemanticVersion,
isBuiltIn: boolean
) {
mockIsOfficialUnityPackage(packageName, isBuiltIn);

if (isBuiltIn) mockMissingRegistryPackument(unityRegistryUrl, packageName);
else
mockRegistryPackument(
unityRegistryUrl,
buildPackument(packageName, (packument) => packument.addVersion(version))
);
}
Original file line number Diff line number Diff line change
@@ -1,21 +1,32 @@
import { mockService } from "./service.mock";
import { GetRegistryPackument } from "../../../src/io/packument-io";
import { CheckIsBuiltInPackage } from "../../../src/services/built-in-package-check";
import { exampleRegistryUrl } from "../domain/data-registry";
import { unityRegistryUrl } from "../../../src/domain/registry-url";
import { DomainName } from "../../../src/domain/domain-name";
import { SemanticVersion } from "../../../src/domain/semantic-version";
import { Registry } from "../../../src/domain/registry";
import { NodeType, tryGetGraphNode } from "../../../src/domain/dependency-graph";
import nock from "nock";
import { PackumentNotFoundError } from "../../../src/common-errors";
import {
NodeType,
tryGetGraphNode,
} from "../../../src/domain/dependency-graph";
import { DomainName } from "../../../src/domain/domain-name";
import { VersionNotFoundError } from "../../../src/domain/packument";
import { ResolveDependenciesFromRegistries } from "../../../src/services/dependency-resolving";
import { Registry, unityRegistry } from "../../../src/domain/registry";
import { unityRegistryUrl } from "../../../src/domain/registry-url";
import { SemanticVersion } from "../../../src/domain/semantic-version";
import { GetRegistryPackument } from "../../../src/io/packument-io";
import { CheckIsBuiltInPackage } from "../../../src/services/built-in-package-check";
import {
resolveDependencies,
ResolveDependenciesFromRegistries,
} from "../../../src/services/dependency-resolving";
import { buildPackument } from "../../data-packument";
import { exampleRegistryUrl } from "../../unit/domain/data-registry";
import { mockService } from "../../unit/services/service.mock";
import {
mockIsBuiltInPackage,
mockMissingRegistryPackument,
mockRegistryPackument,
} from "../network.mock";

describe("dependency resolving", () => {
const sources: Registry[] = [
{ url: exampleRegistryUrl, auth: null },
{ url: unityRegistryUrl, auth: null },
];
const exampleRegistry: Registry = { url: exampleRegistryUrl, auth: null };
const sources: Registry[] = [exampleRegistry, unityRegistry];

const somePackage = DomainName.parse("com.some.package");
const otherPackage = DomainName.parse("com.other.package");
Expand All @@ -40,12 +51,15 @@ describe("dependency resolving", () => {
} as const;
}

beforeEach(() => {
nock.cleanAll();
});

it("should mark missing packages", async () => {
const { resolveDependencies, getRegistryPackument } = makeDependencies();
getRegistryPackument.mockResolvedValue(null);
mockMissingRegistryPackument(exampleRegistryUrl, somePackage);

const graph = await resolveDependencies(
sources,
[exampleRegistry],
somePackage,
someVersion,
false
Expand All @@ -55,23 +69,21 @@ describe("dependency resolving", () => {
expect(node).toEqual({
type: NodeType.Failed,
errors: {
[sources[0]!.url]: expect.any(PackumentNotFoundError),
[sources[1]!.url]: expect.any(PackumentNotFoundError),
[exampleRegistryUrl]: expect.any(PackumentNotFoundError),
},
});
});

it("should mark missing versions", async () => {
const { resolveDependencies, getRegistryPackument } = makeDependencies();
getRegistryPackument.mockResolvedValue({
name: somePackage,
versions: {
[otherVersion]: { name: somePackage, version: otherVersion },
},
});
mockRegistryPackument(
exampleRegistryUrl,
buildPackument(somePackage, (packument) =>
packument.addVersion(otherVersion)
)
);

const graph = await resolveDependencies(
sources,
[exampleRegistry],
somePackage,
someVersion,
false
Expand All @@ -81,27 +93,23 @@ describe("dependency resolving", () => {
expect(node).toEqual({
type: NodeType.Failed,
errors: {
[sources[0]!.url]: expect.any(VersionNotFoundError),
[sources[1]!.url]: expect.any(VersionNotFoundError),
[exampleRegistryUrl]: expect.any(VersionNotFoundError),
},
});
});

it("should mark resolved remote packages", async () => {
const { resolveDependencies, getRegistryPackument } = makeDependencies();
// The first source does not have the package
getRegistryPackument.mockResolvedValueOnce(null);
mockMissingRegistryPackument(exampleRegistryUrl, somePackage);
// But the second does
getRegistryPackument.mockResolvedValueOnce({
name: somePackage,
versions: {
[someVersion]: {
name: somePackage,
version: someVersion,
dependencies: { [otherPackage]: someVersion },
},
},
});
mockRegistryPackument(
unityRegistryUrl,
buildPackument(somePackage, (packument) =>
packument.addVersion(someVersion, (version) =>
version.addDependency(otherPackage, someVersion)
)
)
);

const graph = await resolveDependencies(
sources,
Expand All @@ -120,8 +128,7 @@ describe("dependency resolving", () => {
});

it("should mark resolved built-in packages", async () => {
const { resolveDependencies, checkIsBuiltInPackage } = makeDependencies();
checkIsBuiltInPackage.mockResolvedValue(true);
mockIsBuiltInPackage(somePackage, someVersion, true);

const graph = await resolveDependencies(
sources,
Expand All @@ -139,20 +146,17 @@ describe("dependency resolving", () => {
});

it("should mark dependencies when resolving shallow", async () => {
const { resolveDependencies, getRegistryPackument } = makeDependencies();
getRegistryPackument.mockResolvedValue({
name: somePackage,
versions: {
[someVersion]: {
name: somePackage,
version: someVersion,
dependencies: { [otherPackage]: someVersion },
},
},
});
mockRegistryPackument(
exampleRegistryUrl,
buildPackument(somePackage, (packument) =>
packument.addVersion(someVersion, (version) =>
version.addDependency(otherPackage, someVersion)
)
)
);

const graph = await resolveDependencies(
sources,
[exampleRegistry],
somePackage,
someVersion,
false
Expand All @@ -165,28 +169,22 @@ describe("dependency resolving", () => {
});

it("should resolve dependencies when resolving deep", async () => {
const { resolveDependencies, getRegistryPackument } = makeDependencies();
// First resolve somePackage
getRegistryPackument.mockResolvedValueOnce({
name: somePackage,
versions: {
[someVersion]: {
name: somePackage,
version: someVersion,
dependencies: { [otherPackage]: someVersion },
},
},
});
// first resolve somePackage
mockRegistryPackument(
exampleRegistryUrl,
buildPackument(somePackage, (packument) =>
packument.addVersion(someVersion, (version) =>
version.addDependency(otherPackage, someVersion)
)
)
);
// then resolve otherPackage
getRegistryPackument.mockResolvedValueOnce({
name: otherPackage,
versions: {
[someVersion]: {
name: otherPackage,
version: someVersion,
},
},
});
mockRegistryPackument(
exampleRegistryUrl,
buildPackument(otherPackage, (packument) =>
packument.addVersion(someVersion)
)
);

const graph = await resolveDependencies(
sources,
Expand All @@ -198,33 +196,26 @@ describe("dependency resolving", () => {
const node = tryGetGraphNode(graph, otherPackage, someVersion);
expect(node).toEqual({
type: NodeType.Resolved,
source: sources[0]!.url,
source: exampleRegistryUrl,
dependencies: {},
});
});

it("should search backup registry if version missing in primary registry", async () => {
const { resolveDependencies, getRegistryPackument } = makeDependencies();
// First resolve somePackage
getRegistryPackument.mockResolvedValueOnce({
name: somePackage,
versions: {
[otherVersion]: {
name: somePackage,
version: otherVersion,
},
},
});
// then resolve otherPackage
getRegistryPackument.mockResolvedValueOnce({
name: somePackage,
versions: {
[someVersion]: {
name: somePackage,
version: someVersion,
},
},
});
// Package is the in the primary registry but not the correct version
mockRegistryPackument(
exampleRegistryUrl,
buildPackument(somePackage, (packument) =>
packument.addVersion(otherVersion)
)
);
// but the right package and version is in the fallbacl
mockRegistryPackument(
unityRegistryUrl,
buildPackument(somePackage, (packument) =>
packument.addVersion(someVersion)
)
);

const graph = await resolveDependencies(
sources,
Expand Down

0 comments on commit 2910098

Please sign in to comment.