Backend: implement PluginLoaders.contractPluginGraphs (#1619)

Note: this doesn't include a WeightedGraph.overrideWeights step.
Because overriding weights isn't related to plugins, this will be
handled as a separate feature, later in the load pipeline.
This commit is contained in:
Robin van Boven 2020-02-04 21:08:51 +01:00 committed by GitHub
parent ffd6c38e4c
commit 5fd43bf62d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 105 additions and 0 deletions

View File

@ -3,6 +3,7 @@
import {TaskReporter} from "../util/taskReporter";
import {type Project} from "../core/project";
import {type WeightedGraph as WeightedGraphT} from "../core/weightedGraph";
import * as WeightedGraph from "../core/weightedGraph";
import {type PluginDeclaration} from "../analysis/pluginDeclaration";
import {type CacheProvider} from "./cache";
import {type GithubToken} from "../plugins/github/token";
@ -123,3 +124,26 @@ export async function createPluginGraphs(
cachedProject: {cache, project},
};
}
/**
* Takes PluginGraphs and merges it into a WeightedGraph with identities contracted.
*/
export async function contractPluginGraphs(
{identity}: PluginLoaders,
{graphs, cachedProject}: PluginGraphs
): Promise<WeightedGraphT> {
const {project} = cachedProject;
const mergedGraph = WeightedGraph.merge(graphs);
// Don't contract when there's no identities. This will prevent unnecessary copying.
if (!project.identities.length) {
return mergedGraph;
}
const discourseServer = project.discourseServer || {serverUrl: null};
const identitySpec = {
identities: project.identities,
discourseServerUrl: discourseServer.serverUrl,
};
return identity.contractIdentities(mergedGraph, identitySpec);
}

View File

@ -10,6 +10,7 @@ import * as PluginLoaders from "./pluginLoaders";
const githubSentinel = graphNode("github-sentinel");
const discourseSentinel = graphNode("discourse-sentinel");
const identitySentinel = graphNode("identity-sentinel");
const mockGithubGraph = () => {
const wg = WeightedGraph.empty();
@ -23,6 +24,12 @@ const mockDiscourseGraph = () => {
return wg;
};
const mockContractedGraph = () => {
const wg = WeightedGraph.empty();
wg.graph.addNode(identitySentinel);
return wg;
};
const mockCacheProvider = () => ({
database: jest.fn(),
});
@ -44,6 +51,7 @@ const mockPluginLoaders = () => ({
},
identity: {
declaration: jest.fn().mockReturnValue(fakeIdentityDec),
contractIdentities: jest.fn().mockReturnValue(mockContractedGraph()),
},
});
@ -269,4 +277,69 @@ describe("src/backend/pluginLoaders", () => {
);
});
});
describe("contractPluginGraphs", () => {
it("should only merge graphs when no identities are defined", async () => {
// Given
const loaders = mockPluginLoaders();
const cache = mockCacheProvider();
const project = createProject({
id: "has-github-and-discourse",
discourseServer: {serverUrl: "http://foo.bar"},
repoIds: [exampleRepoId],
});
const pluginGraphs = ({
graphs: [mockGithubGraph(), mockDiscourseGraph()],
cachedProject: {project, cache},
}: any);
// When
const graph = await PluginLoaders.contractPluginGraphs(
loaders,
pluginGraphs
);
// Then
const expectedGraph = WeightedGraph.merge([
mockGithubGraph(),
mockDiscourseGraph(),
]);
expect(graph).toEqual(expectedGraph);
});
it("should contract identities when they are defined", async () => {
// Given
const loaders = mockPluginLoaders();
const cache = mockCacheProvider();
const project = createProject({
id: "has-github-and-discourse-and-identity",
identities: [{username: "foo", aliases: ["github/foo"]}],
discourseServer: {serverUrl: "http://foo.bar"},
repoIds: [exampleRepoId],
});
const pluginGraphs = ({
graphs: [mockGithubGraph(), mockDiscourseGraph()],
cachedProject: {project, cache},
}: any);
// When
const graph = await PluginLoaders.contractPluginGraphs(
loaders,
pluginGraphs
);
// Then
const {identity} = loaders;
const expectedGraph = WeightedGraph.merge([
mockGithubGraph(),
mockDiscourseGraph(),
]);
expect(graph).toEqual(mockContractedGraph());
expect(identity.contractIdentities).toBeCalledTimes(1);
expect(identity.contractIdentities).toBeCalledWith(expectedGraph, {
identities: project.identities,
discourseServerUrl: (project.discourseServer: any).serverUrl,
});
});
});
});

View File

@ -1,12 +1,20 @@
// @flow
import {type PluginDeclaration} from "../../analysis/pluginDeclaration";
import {type WeightedGraph} from "../../core/weightedGraph";
import {type IdentitySpec} from "./identity";
import {contractIdentities} from "./contractIdentities";
import {declaration} from "./declaration";
export interface Loader {
declaration(): PluginDeclaration;
contractIdentities(
weightedGraph: WeightedGraph,
identitySpec: IdentitySpec
): WeightedGraph;
}
export default ({
declaration: () => declaration,
contractIdentities,
}: Loader);