1
0
Fork 0

feat: add initial labels to project

This commit is contained in:
ssube 2020-08-30 23:29:17 -05:00
parent 0ea5791a8f
commit 1f3cbac598
Signed by: ssube
GPG Key ID: 3EED7B957D362AF1
14 changed files with 124 additions and 14 deletions

View File

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

View File

@ -17,6 +17,7 @@ export interface ResolveInput
| Property | Type | Description |
| --- | --- | --- |
| [flags](./cautious-journey.resolveinput.flags.md) | Array&lt;[FlagLabel](./cautious-journey.flaglabel.md)<!-- -->&gt; | |
| [initial](./cautious-journey.resolveinput.initial.md) | Array&lt;string&gt; | |
| [labels](./cautious-journey.resolveinput.labels.md) | Array&lt;string&gt; | |
| [states](./cautious-journey.resolveinput.states.md) | Array&lt;[StateLabel](./cautious-journey.statelabel.md)<!-- -->&gt; | |

View File

@ -33,6 +33,8 @@ export interface ProjectConfig {
*/
flags: Array<FlagLabel>;
initial: Array<string>;
/**
* Project name or path.
*/

View File

@ -121,6 +121,7 @@ definitions:
- colors
- comment
- flags
- initial
- name
- remote
- states
@ -138,6 +139,11 @@ definitions:
items:
$ref: "#/definitions/flag-label"
default: []
initial:
type: array
items:
type: string
default: []
name:
type: string
remote:

View File

@ -34,6 +34,9 @@ export abstract class BaseRemote<TClient, TOptions extends RemoteOptions> implem
case ChangeVerb.CREATED:
lines.push(`- \`${change.label}\` was created by \`${change.cause}\`.`);
break;
case ChangeVerb.INITIAL:
lines.push(`- \`${change.label}\` is an initial label.`);
break;
case ChangeVerb.REMOVED:
lines.push(`- \`${change.label}\` was removed by \`${change.cause}\`.`);
break;

View File

@ -10,6 +10,7 @@ export enum ChangeVerb {
BECAME = 'became',
CONFLICTED = 'conflicted',
CREATED = 'created',
INITIAL = 'initial',
REMOVED = 'removed',
REQUIRED = 'required',
}
@ -44,6 +45,7 @@ export interface ErrorRecord {
*/
export interface ResolveInput {
flags: Array<FlagLabel>;
initial: Array<string>;
labels: Array<string>;
states: Array<StateLabel>;
}
@ -187,19 +189,33 @@ export function resolveProject(options: ResolveInput): ResolveResult {
errors: [],
labels: [],
};
const activeLabels = new Set(options.labels);
const sortedFlags = prioritySort(options.flags);
for (const flag of sortedFlags) {
resolveBaseLabel(flag, result, activeLabels);
if (options.labels.length === 0) {
result.labels.push(...options.initial);
for (const i of options.initial) {
result.changes.push({
cause: '',
effect: ChangeVerb.INITIAL,
label: i,
});
}
} else {
const activeLabels = new Set(options.labels);
const sortedFlags = prioritySort(options.flags);
for (const flag of sortedFlags) {
resolveBaseLabel(flag, result, activeLabels);
}
const sortedStates = prioritySort(options.states);
for (const state of sortedStates) {
resolveState(state, result, activeLabels);
}
result.labels.push(...activeLabels);
}
const sortedStates = prioritySort(options.states);
for (const state of sortedStates) {
resolveState(state, result, activeLabels);
}
result.labels = Array.from(activeLabels).sort();
result.labels.sort();
return result;
}

View File

@ -30,6 +30,7 @@ export async function syncIssueLabels(options: SyncOptions): Promise<unknown> {
const { changes, errors, labels } = resolveProject({
flags: project.flags,
initial: project.initial,
labels: issue.labels,
states: project.states,
});

View File

@ -34,6 +34,7 @@ describe('main app', () => {
colors: [],
comment: false,
flags: [],
initial: [],
name: '',
remote: {
data: {},
@ -68,6 +69,7 @@ describe('main app', () => {
colors: [],
comment: false,
flags: [],
initial: [],
name: '',
remote: {
data: {},
@ -103,6 +105,7 @@ describe('main app', () => {
colors: [],
comment: false,
flags: [],
initial: [],
name: 'bar',
remote: {
data: {},

View File

@ -10,6 +10,7 @@ describe('resolve labels', () => {
it('should return the existing labels', () => {
const result = resolveProject({
flags: [],
initial: [],
labels: TEST_LABELS,
states: [],
});
@ -20,6 +21,7 @@ describe('resolve labels', () => {
it('should not make any changes', () => {
const result = resolveProject({
flags: [],
initial: [],
labels: TEST_LABELS,
states: [],
});
@ -28,6 +30,20 @@ describe('resolve labels', () => {
});
});
describe('with empty labels', () => {
it('should return initial labels', () => {
const initial = ['bar', 'foo'];
const result = resolveProject({
flags: [],
initial,
labels: [],
states: [],
});
expect(result.labels).to.deep.equal(initial);
});
});
// procedural tests
describe('resolver test cases', () => {
for (const test of TEST_CASES) {

View File

@ -97,7 +97,12 @@ describe('github remote', () => {
const remote = await container.create(GithubRemote, REMOTE_OPTIONS);
for (const effect of [ChangeVerb.CONFLICTED, ChangeVerb.CREATED, ChangeVerb.REMOVED, ChangeVerb.REQUIRED]) {
for (const effect of [
ChangeVerb.CONFLICTED,
ChangeVerb.CREATED,
ChangeVerb.REMOVED,
ChangeVerb.REQUIRED,
]) {
const body = remote.formatBody({
changes: [{
cause: 'foo',
@ -112,6 +117,32 @@ describe('github remote', () => {
expect(body).to.include('bar').and.include('foo');
}
});
it('should include initial labels', async () => {
const module = new RemoteModule();
const container = Container.from(module);
await container.configure();
const client = new Octokit();
stub(client.issues, 'createLabel');
module.bind(Octokit).toInstance(client);
const remote = await container.create(GithubRemote, REMOTE_OPTIONS);
const body = remote.formatBody({
changes: [{
cause: 'foo',
effect: ChangeVerb.INITIAL,
label: 'bar',
}],
errors: [],
issue: '',
project: '',
});
expect(body).to.include('bar').and.include('initial');
});
});
describe('create comment endpoint', () => {

View File

@ -2,8 +2,6 @@ import { expect } from 'chai';
import { resolveProject } from '../../src/resolve';
const TEST_LABELS = ['foo', 'bar'];
describe('resolve labels', () => {
describe('flags with unfulfilled requires rule', () => {
it('should be removed when required label is missing', () => {
@ -17,6 +15,7 @@ describe('resolve labels', () => {
name: 'linda',
}],
}],
initial: [],
labels: ['gayle'],
states: [],
});
@ -37,6 +36,7 @@ describe('resolve labels', () => {
name: 'linda',
}],
}],
initial: [],
labels: ['gayle', 'linda'],
states: [],
});
@ -57,6 +57,7 @@ describe('resolve labels', () => {
removes: [],
requires: [],
}],
initial: [],
labels: ['bob'],
states: [],
});
@ -77,6 +78,7 @@ describe('resolve labels', () => {
}],
requires: [],
}],
initial: [],
labels: ['bob', 'hugo'],
states: [],
});

View File

@ -114,6 +114,7 @@ const DEPENDENT_FLAG: FlagLabel = {
export const TEST_CASES: Array<ResolveTestCase> = [{
input: {
flags: [],
initial: [],
labels: [],
states: [],
},
@ -126,6 +127,7 @@ export const TEST_CASES: Array<ResolveTestCase> = [{
}, {
input: {
flags: [SIMPLE_FLAG],
initial: [],
labels: [
'test',
],
@ -142,6 +144,7 @@ export const TEST_CASES: Array<ResolveTestCase> = [{
}, {
input: {
flags: [],
initial: [],
labels: ['foo/bar', 'next'],
states: [TWO_STATE_CYCLE],
},
@ -153,6 +156,7 @@ export const TEST_CASES: Array<ResolveTestCase> = [{
}, {
input: {
flags: [],
initial: [],
labels: ['foo/bar', 'next', 'bob'],
states: [TWO_STATE_CYCLE],
},
@ -164,6 +168,7 @@ export const TEST_CASES: Array<ResolveTestCase> = [{
}, {
input: {
flags: [],
initial: [],
labels: ['foo/bar', 'foo/bin'],
states: [TWO_STATE_CYCLE],
},
@ -175,6 +180,7 @@ export const TEST_CASES: Array<ResolveTestCase> = [{
}, {
input: {
flags: [],
initial: [],
labels: ['foo/bar', 'foo/bin'],
states: [SECOND_STATE_FALLBACK],
},
@ -186,6 +192,7 @@ export const TEST_CASES: Array<ResolveTestCase> = [{
}, {
input: {
flags: [],
initial: [],
labels: ['foo/bar', 'foo/bin', 'bob'],
states: [SECOND_STATE_FALLBACK],
},
@ -197,6 +204,7 @@ export const TEST_CASES: Array<ResolveTestCase> = [{
}, {
input: {
flags: [],
initial: [],
labels: ['foo/bin', 'bob'],
states: [SECOND_STATE_FALLBACK],
},
@ -208,6 +216,7 @@ export const TEST_CASES: Array<ResolveTestCase> = [{
}, {
input: {
flags: [DEPENDENT_FLAG],
initial: [],
labels: ['test', 'bar'],
states: [],
},
@ -219,6 +228,7 @@ export const TEST_CASES: Array<ResolveTestCase> = [{
}, {
input: {
flags: [DEPENDENT_FLAG],
initial: [],
labels: ['bar'],
states: [],
},
@ -230,6 +240,7 @@ export const TEST_CASES: Array<ResolveTestCase> = [{
}, {
input: {
flags: [DEPENDENT_FLAG, SIMPLE_FLAG],
initial: [],
labels: [],
states: [TWO_STATE_CYCLE, SECOND_STATE_FALLBACK],
},

View File

@ -46,6 +46,7 @@ describe('issue sync', () => {
name: 'yep',
}],
}],
initial: [],
name: 'foo',
remote: remoteData,
states: [],

View File

@ -66,6 +66,7 @@ describe('project sync', () => {
],
comment: true,
flags: [TEST_FLAG],
initial: [],
name: '',
remote: remoteConfig,
states: [],
@ -112,6 +113,7 @@ describe('project sync', () => {
colors: [],
comment: true,
flags: [TEST_FLAG],
initial: [],
name: '',
remote: remoteConfig,
states: [],
@ -148,6 +150,7 @@ describe('project sync', () => {
colors: [],
comment: true,
flags: [],
initial: [],
name: '',
remote: remoteConfig,
states: [TEST_STATE],
@ -191,6 +194,7 @@ describe('project sync', () => {
colors: [],
comment: true,
flags: [],
initial: [],
name: '',
remote: remoteConfig,
states: [],
@ -231,6 +235,7 @@ describe('project sync', () => {
colors: [],
comment: false,
flags: [],
initial: [],
name: '',
remote: {
data: {},
@ -262,6 +267,7 @@ describe('project sync', () => {
colors: [],
comment: false,
flags: [],
initial: [],
name: '',
remote: {
data: {},