mirror of
https://github.com/status-im/sourcecred.git
synced 2025-02-10 19:46:34 +00:00
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:
parent
ffd6c38e4c
commit
5fd43bf62d
@ -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);
|
||||
}
|
||||
|
@ -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,
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user