Initiatives: use common timestamp types and utils (#1749)

In PR #1746 we've added `src/util/timestamp.js`. This commit replaces the
plugin's internal opaque string and number types with well tested types
and conversion functions.
This commit is contained in:
Robin van Boven 2020-04-15 14:50:12 +02:00 committed by GitHub
parent 7caca360a0
commit 48a7659ff9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 16 additions and 11 deletions

View File

@ -8,6 +8,7 @@ import {
} from "../../core/graph";
import * as Weights from "../../core/weights";
import type {ReferenceDetector, URL} from "../../core/references";
import * as Timestamp from "../../util/timestamp";
import type {Initiative, InitiativeRepository} from "./initiative";
import {createId, addressFromId} from "./initiative";
import {createWeightedGraph, initiativeWeight} from "./createGraph";
@ -23,7 +24,7 @@ function _createInitiative(overrides?: $Shape<Initiative>): Initiative {
return {
id: createId("UNSET_SUBTYPE", "42"),
title: "Unset test initiative",
timestampMs: 123,
timestampMs: Timestamp.fromNumber(123),
completed: false,
dependencies: [],
references: [],
@ -49,7 +50,7 @@ class MockInitiativeRepository implements InitiativeRepository {
const initiative = _createInitiative({
id: createId("TEST_SUBTYPE", String(num)),
title: `Example Initiative ${num}`,
timestampMs: 400 + num,
timestampMs: Timestamp.fromNumber(400 + num),
...shape,
});

View File

@ -3,6 +3,7 @@
import {type URL} from "../../core/references";
import {type NodeAddressT, NodeAddress} from "../../core/graph";
import {type NodeWeight} from "../../core/weights";
import {type TimestampMs} from "../../util/timestamp";
import {initiativeNodeType} from "./declaration";
// Composite ID, used as input for NodeAddressT.
@ -44,7 +45,7 @@ export type InitiativeWeight = {|
export type Initiative = {|
+id: InitiativeId,
+title: string,
+timestampMs: number,
+timestampMs: TimestampMs,
+weight?: InitiativeWeight,
+completed: boolean,
+dependencies: $ReadOnlyArray<URL>,

View File

@ -1,6 +1,7 @@
// @flow
import {type URL} from "../../core/references";
import {type TimestampISO} from "../../util/timestamp";
import {type NodeAddressT, NodeAddress} from "../../core/graph";
import {type Compatible, fromCompat, toCompat} from "../../util/compat";
import {initiativeNodeType} from "./declaration";
@ -17,7 +18,7 @@ export const INITIATIVE_FILE_SUBTYPE = "INITIATIVE_FILE";
*/
export type InitiativeFile = {|
+title: string,
+timestampIso: ISOTimestamp,
+timestampIso: TimestampISO,
+weight: InitiativeWeight,
+completed: boolean,
+dependencies: $ReadOnlyArray<URL>,
@ -26,9 +27,6 @@ export type InitiativeFile = {|
+champions: $ReadOnlyArray<URL>,
|};
// Note: setting this to opaque forces us to convert it to timestampMs.
opaque type ISOTimestamp: string = string;
const COMPAT_INFO = {type: "sourcecred/initiativeFile", version: "0.1.0"};
export function fromJSON(j: Compatible<any>): InitiativeFile {

View File

@ -1,6 +1,7 @@
// @flow
import {NodeAddress} from "../../core/graph";
import * as Timestamp from "../../util/timestamp";
import {createId, addressFromId} from "./initiative";
import {type InitiativesDirectory} from "./initiativesDirectory";
import {
@ -13,7 +14,7 @@ import {
const exampleInitiativeFile = (): InitiativeFile => ({
title: "Sample initiative",
timestampIso: ("2020-01-08T22:01:57.766Z": any),
timestampIso: Timestamp.toISO(Date.parse("2020-01-08T22:01:57.766Z")),
weight: {incomplete: 360, complete: 420},
completed: false,
champions: ["http://foo.bar/champ"],

View File

@ -5,6 +5,7 @@ import fs from "fs-extra";
import globby from "globby";
import {type URL} from "../../core/references";
import {type NodeAddressT} from "../../core/graph";
import * as Timestamp from "../../util/timestamp";
import {compatReader} from "../../backend/compatIO";
import {
type ReferenceDetector,
@ -148,10 +149,11 @@ export function _convertToInitiatives(
const initiatives = [];
for (const [fileName, initiativeFile] of map.entries()) {
const {timestampIso, ...partialInitiativeFile} = initiativeFile;
const timestampMs = Timestamp.fromISO(timestampIso);
const initiative: Initiative = {
...partialInitiativeFile,
id: initiativeFileId(directory, fileName),
timestampMs: Date.parse(timestampIso),
timestampMs,
};
initiatives.push(initiative);
}

View File

@ -5,6 +5,7 @@ import path from "path";
import fs from "fs-extra";
import stringify from "json-stable-stringify";
import {MappedReferenceDetector} from "../../core/references";
import * as Timestamp from "../../util/timestamp";
import {type Initiative, createId, addressFromId} from "./initiative";
import {
type InitiativesDirectory,
@ -20,7 +21,7 @@ import {type InitiativeFile} from "./initiativeFile";
const exampleInitiativeFile = (): InitiativeFile => ({
title: "Sample initiative",
timestampIso: ("2020-01-08T22:01:57.766Z": any),
timestampIso: Timestamp.toISO(Date.parse("2020-01-08T22:01:57.766Z")),
weight: {incomplete: 360, complete: 420},
completed: false,
champions: ["http://foo.bar/champ"],
@ -31,10 +32,11 @@ const exampleInitiativeFile = (): InitiativeFile => ({
const exampleInitiative = (remoteUrl: string, fileName: string): Initiative => {
const {timestampIso, ...partialInitiativeFile} = exampleInitiativeFile();
const timestampMs = Timestamp.fromISO(timestampIso);
return {
...partialInitiativeFile,
id: createId("INITIATIVE_FILE", remoteUrl, fileName),
timestampMs: Date.parse((timestampIso: any)),
timestampMs,
};
};