Add RelationalView.{to,from}JSON (#443)
This adds methods for serializing the GitHub RelationalView. We have not put in the work to ensure that these methods generate canonical data. Getting the issues in a different order, or finding references in a different order, can change the JSON output even if the resulting repositories are equivalent. @decentralion think it's not worth putting in the effort, since we may switch to a SQL database soon anyway. Test plan: travis Paired with @wchargin
This commit is contained in:
parent
64df5b09c3
commit
6356c5477f
|
@ -1,5 +1,6 @@
|
|||
// @flow
|
||||
|
||||
import {toCompat, fromCompat, type Compatible} from "../../util/compat";
|
||||
import stringify from "json-stable-stringify";
|
||||
import {parseReferences} from "./parseReferences";
|
||||
import * as N from "./nodes";
|
||||
|
@ -22,6 +23,11 @@ import {
|
|||
reviewCommentUrlToId,
|
||||
} from "./urlIdParse";
|
||||
|
||||
const COMPAT_INFO = {
|
||||
type: "sourcecred/github/relationalView",
|
||||
version: "0.1.0",
|
||||
};
|
||||
|
||||
export class RelationalView {
|
||||
_repos: Map<N.RawAddress, RepoEntry>;
|
||||
_issues: Map<N.RawAddress, IssueEntry>;
|
||||
|
@ -164,6 +170,34 @@ export class RelationalView {
|
|||
yield* this.userlikes();
|
||||
}
|
||||
|
||||
toJSON(): RelationalViewJSON {
|
||||
const rawJSON = {
|
||||
repos: addressMapToObject(this._repos),
|
||||
issues: addressMapToObject(this._issues),
|
||||
pulls: addressMapToObject(this._pulls),
|
||||
reviews: addressMapToObject(this._reviews),
|
||||
comments: addressMapToObject(this._comments),
|
||||
userlikes: addressMapToObject(this._userlikes),
|
||||
references: addressMapToObject(this._mapReferences),
|
||||
referencedBy: addressMapToObject(this._mapReferencedBy),
|
||||
};
|
||||
return toCompat(COMPAT_INFO, rawJSON);
|
||||
}
|
||||
|
||||
static fromJSON(compatJson: RelationalViewJSON): RelationalView {
|
||||
const json = fromCompat(COMPAT_INFO, compatJson);
|
||||
const rv = new RelationalView();
|
||||
rv._repos = objectToAddressMap(json.repos);
|
||||
rv._issues = objectToAddressMap(json.issues);
|
||||
rv._pulls = objectToAddressMap(json.pulls);
|
||||
rv._reviews = objectToAddressMap(json.reviews);
|
||||
rv._comments = objectToAddressMap(json.comments);
|
||||
rv._userlikes = objectToAddressMap(json.userlikes);
|
||||
rv._mapReferences = objectToAddressMap(json.references);
|
||||
rv._mapReferencedBy = objectToAddressMap(json.referencedBy);
|
||||
return rv;
|
||||
}
|
||||
|
||||
_addRepo(json: Q.RepositoryJSON) {
|
||||
const address: RepoAddress = {
|
||||
type: N.REPO_TYPE,
|
||||
|
@ -736,3 +770,36 @@ export type TextContentEntity = Issue | Pull | Review | Comment;
|
|||
export type ParentEntity = Repo | Issue | Pull | Review;
|
||||
export type ChildEntity = Issue | Pull | Review | Comment;
|
||||
export type ReferentEntity = Repo | Issue | Pull | Review | Comment | Userlike;
|
||||
|
||||
function addressMapToObject<T>(
|
||||
x: Map<N.RawAddress, T>
|
||||
): AddressEntryMapJSON<T> {
|
||||
const result: {[N.RawAddress]: T} = {};
|
||||
for (const [address, entry] of x.entries()) {
|
||||
result[address] = entry;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function objectToAddressMap<T>(
|
||||
x: AddressEntryMapJSON<T>
|
||||
): Map<N.RawAddress, T> {
|
||||
const result = new Map();
|
||||
for (const key of Object.keys(x)) {
|
||||
const address: N.RawAddress = (key: any);
|
||||
result.set(address, x[address]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
export opaque type AddressEntryMapJSON<T> = {[N.RawAddress]: T};
|
||||
export opaque type RelationalViewJSON = Compatible<{|
|
||||
+repos: AddressEntryMapJSON<RepoEntry>,
|
||||
+issues: AddressEntryMapJSON<IssueEntry>,
|
||||
+pulls: AddressEntryMapJSON<PullEntry>,
|
||||
+reviews: AddressEntryMapJSON<ReviewEntry>,
|
||||
+comments: AddressEntryMapJSON<CommentEntry>,
|
||||
+userlikes: AddressEntryMapJSON<UserlikeEntry>,
|
||||
+references: AddressEntryMapJSON<N.ReferentAddress[]>,
|
||||
+referencedBy: AddressEntryMapJSON<N.TextContentAddress[]>,
|
||||
|}>;
|
||||
|
|
|
@ -223,4 +223,13 @@ describe("plugins/github/relationalView", () => {
|
|||
// may be fragile
|
||||
expect(rv1).toEqual(rv2);
|
||||
});
|
||||
|
||||
describe("to/fromJSON", () => {
|
||||
it("to->from->to is identity", () => {
|
||||
const json1 = view.toJSON();
|
||||
const view1 = R.RelationalView.fromJSON(json1);
|
||||
const json2 = view1.toJSON();
|
||||
expect(json1).toEqual(json2);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue