1
0
Fork 0

feat(config): add project comment, state divider to config

This commit is contained in:
ssube 2020-08-18 08:54:57 -05:00 committed by BZ Libby
parent 3a3facb282
commit 2feb5a3c60
16 changed files with 255 additions and 205 deletions

View File

@ -1,11 +1,11 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. --> <!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [cautious-journey](./cautious-journey.md) &gt; [SyncOptions](./cautious-journey.syncoptions.md) &gt; [flags](./cautious-journey.syncoptions.flags.md) [Home](./index.md) &gt; [cautious-journey](./cautious-journey.md) &gt; [StateLabel](./cautious-journey.statelabel.md) &gt; [divider](./cautious-journey.statelabel.divider.md)
## SyncOptions.flags property ## StateLabel.divider property
<b>Signature:</b> <b>Signature:</b>
```typescript ```typescript
flags: Array<FlagLabel>; divider: string;
``` ```

View File

@ -17,5 +17,6 @@ export interface StateLabel extends BaseLabel
| Property | Type | Description | | Property | Type | Description |
| --- | --- | --- | | --- | --- | --- |
| [divider](./cautious-journey.statelabel.divider.md) | string | |
| [values](./cautious-journey.statelabel.values.md) | Array&lt;[StateValue](./cautious-journey.statevalue.md)<!-- -->&gt; | Values for this state. | | [values](./cautious-journey.statelabel.values.md) | Array&lt;[StateValue](./cautious-journey.statevalue.md)<!-- -->&gt; | Values for this state. |

View File

@ -1,11 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [cautious-journey](./cautious-journey.md) &gt; [SyncOptions](./cautious-journey.syncoptions.md) &gt; [colors](./cautious-journey.syncoptions.colors.md)
## SyncOptions.colors property
<b>Signature:</b>
```typescript
colors: Array<string>;
```

View File

@ -14,11 +14,8 @@ export interface SyncOptions
| Property | Type | Description | | Property | Type | Description |
| --- | --- | --- | | --- | --- | --- |
| [colors](./cautious-journey.syncoptions.colors.md) | Array&lt;string&gt; | |
| [flags](./cautious-journey.syncoptions.flags.md) | Array&lt;[FlagLabel](./cautious-journey.flaglabel.md)<!-- -->&gt; | |
| [logger](./cautious-journey.syncoptions.logger.md) | Logger | | | [logger](./cautious-journey.syncoptions.logger.md) | Logger | |
| [project](./cautious-journey.syncoptions.project.md) | string | | | [project](./cautious-journey.syncoptions.project.md) | ProjectConfig | |
| [random](./cautious-journey.syncoptions.random.md) | prng | | | [random](./cautious-journey.syncoptions.random.md) | prng | |
| [remote](./cautious-journey.syncoptions.remote.md) | [Remote](./cautious-journey.remote.md) | | | [remote](./cautious-journey.syncoptions.remote.md) | [Remote](./cautious-journey.remote.md) | |
| [states](./cautious-journey.syncoptions.states.md) | Array&lt;[StateLabel](./cautious-journey.statelabel.md)<!-- -->&gt; | States from project config. |

View File

@ -7,5 +7,5 @@
<b>Signature:</b> <b>Signature:</b>
```typescript ```typescript
project: string; project: ProjectConfig;
``` ```

View File

@ -1,13 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [cautious-journey](./cautious-journey.md) &gt; [SyncOptions](./cautious-journey.syncoptions.md) &gt; [states](./cautious-journey.syncoptions.states.md)
## SyncOptions.states property
States from project config.
<b>Signature:</b>
```typescript
states: Array<StateLabel>;
```

View File

@ -5,40 +5,51 @@ import { FlagLabel, StateLabel } from '../labels';
import { RemoteOptions } from '../remote'; import { RemoteOptions } from '../remote';
import * as SCHEMA_DATA from './schema.yml'; import * as SCHEMA_DATA from './schema.yml';
export interface LoggerConfig {
level: LogLevel;
name: string;
}
export interface ProjectConfig {
/**
* Color palette for labels without their own.
*/
colors: Array<string>;
/**
* Leave a comment along with any update, explaining the changes that were made.
*
* @default `true`
*/
comment: boolean;
/**
* Individual flag labels.
*/
flags: Array<FlagLabel>;
/**
* Project name or path.
*/
name: string;
/**
* Remote APIs.
*/
remote: RemoteOptions;
/**
* Grouped state labels.
*/
states: Array<StateLabel>;
}
/** /**
* Config data for the app, loaded from CLI or DOM. * Config data for the app, loaded from CLI or DOM.
*/ */
export interface ConfigData { export interface ConfigData {
logger: { logger: LoggerConfig;
level: LogLevel; projects: Array<ProjectConfig>;
name: string;
};
projects: Array<{
/**
* Color palette for labels without their own.
*/
colors: Array<string>;
/**
* Individual flag labels.
*/
flags: Array<FlagLabel>;
/**
* Project name or path.
*/
name: string;
/**
* Remote APIs.
*/
remote: RemoteOptions;
/**
* Grouped state labels.
*/
states: Array<StateLabel>;
}>;
} }
/** /**
@ -54,6 +65,7 @@ export function initConfig(): ConfigData {
}, },
projects: [{ projects: [{
colors: [], colors: [],
comment: true,
flags: [], flags: [],
name: '', name: '',
remote: { remote: {
@ -82,5 +94,11 @@ export function validateConfig(it: unknown): it is ConfigData {
const ajv = new Ajv(SCHEMA_OPTIONS); const ajv = new Ajv(SCHEMA_OPTIONS);
ajv.addSchema(SCHEMA_DATA, 'cautious-journey'); ajv.addSchema(SCHEMA_DATA, 'cautious-journey');
return ajv.validate('cautious-journey#/definitions/config', it) === true; if (ajv.validate('cautious-journey#/definitions/config', it) === true) {
return true;
} else {
/* eslint-disable-next-line */
console.error('invalid config', ajv.errors, it);
return false;
}
} }

View File

@ -3,12 +3,17 @@ $id: cautious-journey
definitions: definitions:
label-ref: label-ref:
type: object type: object
required:
- name
properties: properties:
name: name:
type: string type: string
change-set: change-set:
type: object type: object
required:
- adds
- removes
properties: properties:
adds: adds:
type: array type: array
@ -23,6 +28,9 @@ definitions:
base-label: base-label:
type: object type: object
required:
- name
- requires
properties: properties:
color: color:
type: string type: string
@ -59,7 +67,13 @@ definitions:
- $ref: "#/definitions/change-set" - $ref: "#/definitions/change-set"
- $ref: "#/definitions/base-label" - $ref: "#/definitions/base-label"
- type: object - type: object
required:
- divider
- values
properties: properties:
divider:
type: string
default: "/"
values: values:
type: array type: array
items: items:
@ -71,6 +85,8 @@ definitions:
- $ref: "#/definitions/change-set" - $ref: "#/definitions/change-set"
- $ref: "#/definitions/base-label" - $ref: "#/definitions/base-label"
- type: object - type: object
required:
- becomes
properties: properties:
becomes: becomes:
type: array type: array
@ -78,38 +94,60 @@ definitions:
$ref: "#/definitions/state-change" $ref: "#/definitions/state-change"
default: [] default: []
project:
type: object
required:
- colors
- comment
- flags
- name
- remote
- states
properties:
colors:
type: array
items:
type: string
comment:
type: boolean
default: true
flags:
type: array
items:
$ref: "#/definitions/flag-label"
default: []
name:
type: string
remote:
type: object
states:
type: array
items:
$ref: "#/definitions/state-label"
default: []
logger:
type: object
required:
- level
- name
properties:
level:
type: string
name:
type: string
config: config:
type: object type: object
required:
- logger
- projects
properties: properties:
logger: logger:
type: object $ref: "#/definitions/logger"
properties:
level:
type: string
name:
type: string
projects: projects:
type: array type: array
items: items:
type: object $ref: "#/definitions/project"
properties:
colors:
type: array
items:
type: string
flags:
type: array
items:
$ref: "#/definitions/flag-label"
default: []
name:
type: string
remote:
type: object
states:
type: array
items:
$ref: "#/definitions/state-label"
default: []
type: object type: object

View File

@ -14,7 +14,7 @@ const STATUS_ERROR = 1;
*/ */
main(process.argv).then((status) => process.exit(status)).catch((err: Error) => { main(process.argv).then((status) => process.exit(status)).catch((err: Error) => {
// eslint-disable-next-line no-console // eslint-disable-next-line no-console
console.error('uncaught error during main:', err); console.error('uncaught error during main:', err.message);
process.exit(STATUS_ERROR); process.exit(STATUS_ERROR);
}); });

View File

@ -71,6 +71,8 @@ export interface StateValue extends BaseLabel {
* Grouped labels: the equivalent of a radio group. * Grouped labels: the equivalent of a radio group.
*/ */
export interface StateLabel extends BaseLabel { export interface StateLabel extends BaseLabel {
divider: string;
/** /**
* Values for this state. * Values for this state.
*/ */
@ -97,12 +99,12 @@ export function getLabelNames(flags: Array<FlagLabel>, states: Array<StateLabel>
return new Set(labels); return new Set(labels);
} }
export function splitValueName(name: string): Array<string> { export function splitValueName(state: StateLabel, name: string): Array<string> {
return name.split('/'); return name.split(state.divider);
} }
export function getValueName(state: StateLabel, value: StateValue): string { export function getValueName(state: StateLabel, value: StateValue): string {
return `${state.name}/${value.name}`; return `${state.name}${state.divider}${value.name}`;
} }
/** /**

View File

@ -1,4 +1,4 @@
import { doesExist, InvalidArgumentError, isNil } from '@apextoaster/js-utils'; import { doesExist, InvalidArgumentError } from '@apextoaster/js-utils';
import { createSchema } from '@apextoaster/js-yaml-schema'; import { createSchema } from '@apextoaster/js-yaml-schema';
import { existsSync, readFileSync, realpathSync } from 'fs'; import { existsSync, readFileSync, realpathSync } from 'fs';
import { DEFAULT_SAFE_SCHEMA, safeLoad } from 'js-yaml'; import { DEFAULT_SAFE_SCHEMA, safeLoad } from 'js-yaml';
@ -7,11 +7,11 @@ import { alea } from 'seedrandom';
import { ConfigData, validateConfig } from './config'; import { ConfigData, validateConfig } from './config';
import { Commands, createParser } from './config/args'; import { Commands, createParser } from './config/args';
import { dotGraph, graphLabels } from './graph';
import { BunyanLogger } from './logger/bunyan'; import { BunyanLogger } from './logger/bunyan';
import { GithubRemote } from './remote/github'; import { GithubRemote } from './remote/github';
import { syncIssueLabels, SyncOptions, syncProjectLabels } from './sync'; import { syncIssueLabels, SyncOptions, syncProjectLabels } from './sync';
import { VERSION_INFO } from './version'; import { VERSION_INFO } from './version';
import { graphLabels, dotGraph } from './graph';
export { FlagLabel, StateLabel } from './labels'; export { FlagLabel, StateLabel } from './labels';
export { Remote, RemoteOptions } from './remote'; export { Remote, RemoteOptions } from './remote';
@ -38,7 +38,7 @@ async function loadConfig(path: string): Promise<ConfigData> {
const config = safeLoad(rawConfig, { schema }); const config = safeLoad(rawConfig, { schema });
if (!validateConfig(config)) { if (!validateConfig(config)) {
throw new Error(); throw new InvalidArgumentError();
} }
return config as ConfigData; return config as ConfigData;
@ -52,14 +52,16 @@ export async function main(argv: Array<string>): Promise<number> {
const logger = BunyanLogger.create(config.logger); const logger = BunyanLogger.create(config.logger);
logger.info({ logger.info({
args,
config,
mode, mode,
version: VERSION_INFO, version: VERSION_INFO,
}, 'startup environment'); }, 'running main');
logger.debug({
args,
config,
}, 'runtime data');
for (const project of config.projects) { for (const project of config.projects) {
const { colors, flags, name, states } = project; const { name } = project;
if (doesExist(args.project) && !args.project.includes(name)) { if (doesExist(args.project) && !args.project.includes(name)) {
logger.info({ project: name }, 'skipping project'); logger.info({ project: name }, 'skipping project');
@ -77,13 +79,10 @@ export async function main(argv: Array<string>): Promise<number> {
// mode switch // mode switch
const options: SyncOptions = { const options: SyncOptions = {
colors,
flags,
logger, logger,
project: name, project,
random, random,
remote, remote,
states,
}; };
switch (mode) { switch (mode) {
case Commands.GRAPH: case Commands.GRAPH:

View File

@ -133,40 +133,45 @@ export function resolveLabels(options: ResolveInput): ResolveResult {
label: name, label: name,
}); });
} }
} else {
const combinedValue: BaseLabel = {
adds: [...state.adds, ...value.adds],
name,
priority: defaultUntil(value.priority, state.priority, 0),
removes: [...state.removes, ...value.removes],
requires: [...state.requires, ...value.requires],
};
if (checkLabelRules(combinedValue)) { continue;
continue; }
}
let removed = false; const combinedValue: BaseLabel = {
for (const become of value.becomes) { adds: [...state.adds, ...value.adds],
if (become.matches.every((l) => activeLabels.has(l.name))) { name,
checkLabelRules({ priority: defaultUntil(value.priority, state.priority, 0),
...combinedValue, removes: [...state.removes, ...value.removes],
adds: become.adds, requires: [...state.requires, ...value.requires],
removes: [...become.matches, ...become.removes], };
requires: [],
if (checkLabelRules(combinedValue)) {
continue;
}
// TODO: flatten this bit and remove the mutable boolean
let removed = false;
for (const become of value.becomes) {
const matches = become.matches.every((l) => activeLabels.has(l.name));
if (matches) {
checkLabelRules({
...combinedValue,
adds: become.adds,
removes: [...become.matches, ...become.removes],
requires: [],
});
if (activeLabels.delete(name)) {
changes.push({
cause: name,
effect: ChangeVerb.REMOVED,
label: name,
}); });
removed = true;
if (activeLabels.delete(name)) {
changes.push({
cause: name,
effect: ChangeVerb.REMOVED,
label: name,
});
removed = true;
}
break;
} }
break;
} }
if (removed) { if (removed) {

View File

@ -6,25 +6,13 @@ import { FlagLabel, getLabelColor, getLabelNames, getValueName, StateLabel } fro
import { LabelUpdate, Remote } from './remote'; import { LabelUpdate, Remote } from './remote';
import { resolveLabels } from './resolve'; import { resolveLabels } from './resolve';
import { defaultTo, defaultUntil, compareItems } from './utils'; import { defaultTo, defaultUntil, compareItems } from './utils';
import { ProjectConfig } from './config';
export interface SyncOptions { export interface SyncOptions {
/**
*/
colors: Array<string>;
/**
*/
flags: Array<FlagLabel>;
logger: Logger; logger: Logger;
project: string; project: ProjectConfig;
random: prng; random: prng;
remote: Remote; remote: Remote;
/**
* States from project config.
*/
states: Array<StateLabel>;
} }
/** /**
@ -32,34 +20,38 @@ export interface SyncOptions {
* if there are changes and no errors, then updates the issue. * if there are changes and no errors, then updates the issue.
*/ */
export async function syncIssueLabels(options: SyncOptions): Promise<unknown> { export async function syncIssueLabels(options: SyncOptions): Promise<unknown> {
const issues = await options.remote.listIssues({ const { logger, project, remote } = options;
project: options.project, const issues = await remote.listIssues({
project: project.name,
}); });
for (const issue of issues) { for (const issue of issues) {
options.logger.info({ issue }, 'project issue'); logger.info({ issue }, 'project issue');
const { changes, errors, labels } = resolveLabels({ const { changes, errors, labels } = resolveLabels({
flags: options.flags, flags: project.flags,
labels: issue.labels, labels: issue.labels,
states: options.states, states: project.states,
}); });
options.logger.debug({ changes, errors, issue, labels }, 'resolved labels'); logger.debug({ changes, errors, issue, labels }, 'resolved labels');
// TODO: prompt user to update this particular issue // TODO: prompt user to update this particular issue
const sameLabels = compareItems(issue.labels, labels) || changes.length === 0; const sameLabels = compareItems(issue.labels, labels) || changes.length === 0;
if (sameLabels === false && errors.length === 0) { if (sameLabels === false && errors.length === 0) {
options.logger.info({ changes, errors, issue, labels }, 'updating issue'); logger.info({ changes, errors, issue, labels }, 'updating issue');
await options.remote.updateIssue({ await remote.updateIssue({
...issue, ...issue,
labels, labels,
}); });
await options.remote.createComment({
...issue, if (project.comment) {
changes, await remote.createComment({
errors, ...issue,
}); changes,
errors,
});
}
} }
} }
@ -67,19 +59,21 @@ export async function syncIssueLabels(options: SyncOptions): Promise<unknown> {
} }
export async function syncProjectLabels(options: SyncOptions): Promise<unknown> { export async function syncProjectLabels(options: SyncOptions): Promise<unknown> {
const labels = await options.remote.listLabels({ const { logger, project, remote } = options;
project: options.project,
const labels = await remote.listLabels({
project: project.name,
}); });
const present = new Set(labels.map((l) => l.name)); const present = new Set(labels.map((l) => l.name));
const desired = getLabelNames(options.flags, options.states); const desired = getLabelNames(project.flags, project.states);
const combined = new Set([...desired, ...present]); const combined = new Set([...desired, ...present]);
for (const label of combined) { for (const label of combined) {
const exists = present.has(label); const exists = present.has(label);
const expected = desired.has(label); const expected = desired.has(label);
options.logger.info({ logger.info({
exists, exists,
expected, expected,
label, label,
@ -90,15 +84,15 @@ export async function syncProjectLabels(options: SyncOptions): Promise<unknown>
const data = mustExist(labels.find((l) => l.name === label)); const data = mustExist(labels.find((l) => l.name === label));
await syncSingleLabel(options, data); await syncSingleLabel(options, data);
} else { } else {
options.logger.warn({ label }, 'remove label'); logger.warn({ label }, 'remove label');
await options.remote.deleteLabel({ await remote.deleteLabel({
name: label, name: label,
project: options.project, project: project.name,
}); });
} }
} else { } else {
if (expected) { if (expected) {
options.logger.info({ label }, 'create label'); logger.info({ label }, 'create label');
await createLabel(options, label); await createLabel(options, label);
} else { } else {
// skip // skip
@ -110,27 +104,29 @@ export async function syncProjectLabels(options: SyncOptions): Promise<unknown>
} }
export async function createLabel(options: SyncOptions, name: string) { export async function createLabel(options: SyncOptions, name: string) {
const flag = options.flags.find((it) => name === it.name); const { project, remote } = options;
const flag = project.flags.find((it) => name === it.name);
if (doesExist(flag)) { if (doesExist(flag)) {
await options.remote.createLabel({ await remote.createLabel({
color: getLabelColor(options.colors, options.random, flag), color: getLabelColor(project.colors, options.random, flag),
desc: mustExist(flag.desc), desc: mustExist(flag.desc),
name, name,
project: options.project, project: project.name,
}); });
return; return;
} }
const state = options.states.find((it) => name.startsWith(it.name)); const state = project.states.find((it) => name.startsWith(it.name));
if (doesExist(state)) { if (doesExist(state)) {
const value = state.values.find((it) => getValueName(state, it) === name); const value = state.values.find((it) => getValueName(state, it) === name);
if (doesExist(value)) { if (doesExist(value)) {
await options.remote.createLabel({ await remote.createLabel({
color: getLabelColor(options.colors, options.random, state, value), color: getLabelColor(project.colors, options.random, state, value),
desc: defaultUntil(value.desc, state.desc, ''), desc: defaultUntil(value.desc, state.desc, ''),
name: getValueName(state, value), name: getValueName(state, value),
project: options.project, project: project.name,
}); });
return; return;
@ -139,6 +135,8 @@ export async function createLabel(options: SyncOptions, name: string) {
} }
export async function syncLabelDiff(options: SyncOptions, oldLabel: LabelUpdate, newLabel: LabelUpdate) { export async function syncLabelDiff(options: SyncOptions, oldLabel: LabelUpdate, newLabel: LabelUpdate) {
const { logger, project } = options;
const dirty = const dirty =
oldLabel.color !== mustExist(newLabel.color) || oldLabel.color !== mustExist(newLabel.color) ||
oldLabel.desc !== mustExist(newLabel.desc); oldLabel.desc !== mustExist(newLabel.desc);
@ -148,41 +146,40 @@ export async function syncLabelDiff(options: SyncOptions, oldLabel: LabelUpdate,
color: defaultTo(newLabel.color, oldLabel.color), color: defaultTo(newLabel.color, oldLabel.color),
desc: defaultTo(newLabel.desc, oldLabel.desc), desc: defaultTo(newLabel.desc, oldLabel.desc),
name: oldLabel.name, name: oldLabel.name,
project: options.project, project: project.name,
}; };
options.logger.debug({ body, newLabel, oldLabel }, 'update label'); logger.debug({ body, newLabel, oldLabel }, 'updating label');
const resp = await options.remote.updateLabel(body); const resp = await options.remote.updateLabel(body);
logger.debug({ resp }, 'update response');
options.logger.debug({ resp }, 'update resp');
} }
} }
export async function syncSingleLabel(options: SyncOptions, label: LabelUpdate): Promise<void> { export async function syncSingleLabel(options: SyncOptions, label: LabelUpdate): Promise<void> {
const flag = options.flags.find((it) => label.name === it.name); const { project } = options;
const flag = project.flags.find((it) => label.name === it.name);
if (doesExist(flag)) { if (doesExist(flag)) {
const color = getLabelColor(options.colors, options.random, flag); const color = getLabelColor(project.colors, options.random, flag);
await syncLabelDiff(options, label, { await syncLabelDiff(options, label, {
color, color,
desc: defaultTo(flag.desc, label.desc), desc: defaultTo(flag.desc, label.desc),
name: flag.name, name: flag.name,
project: options.project, project: project.name,
}); });
return; return;
} }
const state = options.states.find((it) => label.name.startsWith(it.name)); const state = project.states.find((it) => label.name.startsWith(it.name));
if (doesExist(state)) { if (doesExist(state)) {
const value = state.values.find((it) => getValueName(state, it) === label.name); const value = state.values.find((it) => getValueName(state, it) === label.name);
if (doesExist(value)) { if (doesExist(value)) {
const color = mustExist(getLabelColor(options.colors, options.random, state, value)); const color = mustExist(getLabelColor(project.colors, options.random, state, value));
await syncLabelDiff(options, label, { await syncLabelDiff(options, label, {
color, color,
desc: defaultTo(value.desc, label.desc), desc: defaultTo(value.desc, label.desc),
name: getValueName(state, value), name: getValueName(state, value),
project: options.project, project: project.name,
}); });
return; return;

View File

@ -35,3 +35,11 @@ export function compareItems<T>(a: Array<T>, b: Array<T>): boolean {
return true; return true;
} }
interface Collection<T> {
has(value: T): boolean;
}
export function contains<T>(a: Collection<T>, b: Array<T>): boolean {
return b.every((it) => a.has(it));
}

View File

@ -1,7 +1,7 @@
import { expect } from 'chai'; import { expect } from 'chai';
import { alea } from 'seedrandom'; import { alea } from 'seedrandom';
import { getLabelColor, getLabelNames, prioritySort } from '../src/labels'; import { getLabelColor, getLabelNames, prioritySort, StateLabel } from '../src/labels';
describe('label helpers', () => { describe('label helpers', () => {
describe('label name helper', () => { describe('label name helper', () => {
@ -38,8 +38,9 @@ describe('label helpers', () => {
removes: [], removes: [],
requires: [], requires: [],
}]; }];
const states = [{ const states: Array<StateLabel> = [{
adds: [], adds: [],
divider: '/',
name: 'foo', name: 'foo',
priority: 1, priority: 1,
removes: [], removes: [],
@ -47,6 +48,7 @@ describe('label helpers', () => {
values, values,
}, { }, {
adds: [], adds: [],
divider: '/',
name: 'bar', name: 'bar',
priority: 1, priority: 1,
removes: [], removes: [],
@ -109,6 +111,7 @@ describe('label helpers', () => {
expect(getLabelColor(['test'], alea(), { expect(getLabelColor(['test'], alea(), {
adds: [], adds: [],
color: 'beans', color: 'beans',
divider: '/',
name: '', name: '',
priority: 1, priority: 1,
removes: [], removes: [],
@ -129,6 +132,7 @@ describe('label helpers', () => {
expect(getLabelColor(['test'], alea(), { expect(getLabelColor(['test'], alea(), {
adds: [], adds: [],
color: 'beans', color: 'beans',
divider: '/',
name: '', name: '',
priority: 1, priority: 1,
removes: [], removes: [],

View File

@ -12,30 +12,35 @@ describe('label sync', () => {
const logger = BunyanLogger.create({ const logger = BunyanLogger.create({
name: 'test', name: 'test',
}); });
const remote = new GithubRemote({ const remoteConfig = {
data: {}, data: {},
dryrun: true, dryrun: true,
logger, logger,
type: '', type: '',
}); };
const remote = new GithubRemote(remoteConfig);
const updateSpy = spy(remote, 'updateLabel'); const updateSpy = spy(remote, 'updateLabel');
await syncSingleLabel({ await syncSingleLabel({
colors: [
'ff0000',
],
flags: [{
adds: [],
name: 'foo',
priority: 1,
removes: [],
requires: [],
}],
logger, logger,
project: '', project: {
colors: [
'ff0000',
],
comment: true,
flags: [{
adds: [],
name: 'foo',
priority: 1,
removes: [],
requires: [],
}],
name: '',
remote: remoteConfig,
states: [],
},
random: alea(), random: alea(),
remote, remote,
states: [],
}, { }, {
color: '', color: '',
desc: '', desc: '',