fix(test): cover config loading, graph styles
This commit is contained in:
parent
98391a9a47
commit
0ea5791a8f
|
@ -1,9 +1,8 @@
|
||||||
import { InvalidArgumentError } from '@apextoaster/js-utils';
|
import { createConfig } from '@apextoaster/js-config';
|
||||||
import { createSchema } from '@apextoaster/js-yaml-schema';
|
import { IncludeOptions } from '@apextoaster/js-yaml-schema';
|
||||||
import { createConfig, loadFile } from '@apextoaster/js-config';
|
|
||||||
import Ajv from 'ajv';
|
import Ajv from 'ajv';
|
||||||
import { existsSync, readFileSync, realpathSync } from 'fs';
|
import { existsSync, readFileSync, realpathSync } from 'fs';
|
||||||
import { DEFAULT_SAFE_SCHEMA, safeLoad } from 'js-yaml';
|
import { DEFAULT_SAFE_SCHEMA } from 'js-yaml';
|
||||||
import { LogLevel } from 'noicejs';
|
import { LogLevel } from 'noicejs';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
|
|
||||||
|
@ -63,16 +62,8 @@ export const CONFIG_SCHEMA_KEY = 'cautious-journey#/definitions/config';
|
||||||
/**
|
/**
|
||||||
* Load the config from files.
|
* Load the config from files.
|
||||||
*/
|
*/
|
||||||
export async function initConfig(path: string): Promise<ConfigData> {
|
export async function initConfig(path: string, include = SCHEMA_OPTIONS): Promise<ConfigData> {
|
||||||
const include = {
|
const validator = new Ajv(AJV_OPTIONS);
|
||||||
exists: existsSync,
|
|
||||||
join,
|
|
||||||
read: readFileSync,
|
|
||||||
resolve: realpathSync,
|
|
||||||
schema: DEFAULT_SAFE_SCHEMA,
|
|
||||||
};
|
|
||||||
|
|
||||||
const validator = new Ajv(SCHEMA_OPTIONS);
|
|
||||||
validator.addSchema(SCHEMA_DATA, 'cautious-journey');
|
validator.addSchema(SCHEMA_DATA, 'cautious-journey');
|
||||||
|
|
||||||
const config = createConfig<ConfigData>({
|
const config = createConfig<ConfigData>({
|
||||||
|
@ -95,7 +86,7 @@ export async function initConfig(path: string): Promise<ConfigData> {
|
||||||
return config.getData();
|
return config.getData();
|
||||||
}
|
}
|
||||||
|
|
||||||
export const SCHEMA_OPTIONS: Ajv.Options = {
|
export const AJV_OPTIONS: Ajv.Options = {
|
||||||
allErrors: true,
|
allErrors: true,
|
||||||
coerceTypes: 'array',
|
coerceTypes: 'array',
|
||||||
missingRefs: 'fail',
|
missingRefs: 'fail',
|
||||||
|
@ -104,3 +95,11 @@ export const SCHEMA_OPTIONS: Ajv.Options = {
|
||||||
useDefaults: true,
|
useDefaults: true,
|
||||||
verbose: true,
|
verbose: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const SCHEMA_OPTIONS: IncludeOptions = {
|
||||||
|
exists: existsSync,
|
||||||
|
join,
|
||||||
|
read: readFileSync,
|
||||||
|
resolve: realpathSync,
|
||||||
|
schema: DEFAULT_SAFE_SCHEMA,
|
||||||
|
};
|
||||||
|
|
|
@ -126,12 +126,20 @@ describe('graph tools', () => {
|
||||||
|
|
||||||
describe('edge style', () => {
|
describe('edge style', () => {
|
||||||
it('should color edges', () => {
|
it('should color edges', () => {
|
||||||
|
for (const verb of [
|
||||||
|
ChangeVerb.BECAME,
|
||||||
|
ChangeVerb.CONFLICTED,
|
||||||
|
ChangeVerb.CREATED,
|
||||||
|
ChangeVerb.REMOVED,
|
||||||
|
ChangeVerb.REQUIRED,
|
||||||
|
]) {
|
||||||
expect(edgeStyle({
|
expect(edgeStyle({
|
||||||
source: 'foo',
|
source: 'foo',
|
||||||
target: 'bar',
|
target: 'bar',
|
||||||
type: EdgeType.BOTH,
|
type: EdgeType.BOTH,
|
||||||
verb: ChangeVerb.CREATED,
|
verb,
|
||||||
})).to.include('color=');
|
})).to.include('color=');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,60 @@
|
||||||
|
import { IncludeOptions } from '@apextoaster/js-yaml-schema';
|
||||||
import { expect } from 'chai';
|
import { expect } from 'chai';
|
||||||
|
import { DEFAULT_SAFE_SCHEMA } from 'js-yaml';
|
||||||
|
import { match, stub } from 'sinon';
|
||||||
|
|
||||||
|
import { initConfig } from '../../src/config';
|
||||||
|
|
||||||
describe('config', () => {
|
describe('config', () => {
|
||||||
describe('init config', () => {
|
describe('init config', () => {
|
||||||
it('should load a valid config');
|
it('should load a valid config', async () => {
|
||||||
it('should throw on invalid config');
|
const path = 'valid.yml';
|
||||||
|
const include: IncludeOptions = {
|
||||||
|
exists: stub(),
|
||||||
|
join: stub().returns(path),
|
||||||
|
read: stub().returns(`
|
||||||
|
logger:
|
||||||
|
level: info
|
||||||
|
name: test
|
||||||
|
projects: []
|
||||||
|
`),
|
||||||
|
resolve: stub(),
|
||||||
|
schema: DEFAULT_SAFE_SCHEMA,
|
||||||
|
};
|
||||||
|
|
||||||
|
const config = await initConfig(path, include);
|
||||||
|
expect(include.read).to.have.been.calledWith(path, match.object);
|
||||||
|
expect(config.logger.name).to.equal('test');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw on invalid config', async () => {
|
||||||
|
const include: IncludeOptions = {
|
||||||
|
exists: stub(),
|
||||||
|
join: stub().returnsArg(0),
|
||||||
|
read: stub().returns(`
|
||||||
|
logger: []
|
||||||
|
projects: {}
|
||||||
|
`),
|
||||||
|
resolve: stub(),
|
||||||
|
schema: DEFAULT_SAFE_SCHEMA,
|
||||||
|
};
|
||||||
|
|
||||||
|
await expect(initConfig('./invalid.yml', include)).to.eventually.be.rejectedWith(Error);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw on missing paths', async () => {
|
||||||
|
const err = new Error();
|
||||||
|
Reflect.set(err, 'code', 'ENOENT');
|
||||||
|
|
||||||
|
const include: IncludeOptions = {
|
||||||
|
exists: stub().returns(false),
|
||||||
|
join: stub().returnsArg(0),
|
||||||
|
read: stub().throws(err),
|
||||||
|
resolve: stub(),
|
||||||
|
schema: DEFAULT_SAFE_SCHEMA,
|
||||||
|
};
|
||||||
|
|
||||||
|
await expect(initConfig('.fake', include)).to.eventually.be.rejectedWith(Error);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,11 +1,43 @@
|
||||||
|
import { InvalidArgumentError } from '@apextoaster/js-utils';
|
||||||
import { expect } from 'chai';
|
import { expect } from 'chai';
|
||||||
import { Container } from 'noicejs';
|
import { Container, NullLogger } from 'noicejs';
|
||||||
import { alea } from 'seedrandom';
|
import { alea } from 'seedrandom';
|
||||||
import { match, spy, stub } from 'sinon';
|
import { createStubInstance, match, spy, stub } from 'sinon';
|
||||||
|
|
||||||
import { BunyanLogger } from '../../src/logger/bunyan';
|
import { BunyanLogger } from '../../src/logger/bunyan';
|
||||||
import { GithubRemote } from '../../src/remote/github';
|
import { GithubRemote } from '../../src/remote/github';
|
||||||
import { syncProjectLabels, updateLabel } from '../../src/sync';
|
import { syncProjectLabels, updateLabel } from '../../src/sync';
|
||||||
|
import { FlagLabel, StateLabel } from '../../src';
|
||||||
|
|
||||||
|
const TEST_FLAG: FlagLabel = {
|
||||||
|
adds: [],
|
||||||
|
color: 'aabbcc',
|
||||||
|
desc: '',
|
||||||
|
name: 'foo',
|
||||||
|
priority: 1,
|
||||||
|
removes: [],
|
||||||
|
requires: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
const TEST_STATE: StateLabel = {
|
||||||
|
adds: [],
|
||||||
|
color: '',
|
||||||
|
desc: '',
|
||||||
|
divider: '/',
|
||||||
|
name: 'foo',
|
||||||
|
priority: 1,
|
||||||
|
removes: [],
|
||||||
|
requires: [],
|
||||||
|
values: [{
|
||||||
|
adds: [],
|
||||||
|
becomes: [],
|
||||||
|
color: 'aabbcc',
|
||||||
|
name: 'bar',
|
||||||
|
priority: 1,
|
||||||
|
removes: [],
|
||||||
|
requires: [],
|
||||||
|
}],
|
||||||
|
};
|
||||||
|
|
||||||
describe('project sync', () => {
|
describe('project sync', () => {
|
||||||
describe('all labels', () => {
|
describe('all labels', () => {
|
||||||
|
@ -33,13 +65,7 @@ describe('project sync', () => {
|
||||||
'ff0000',
|
'ff0000',
|
||||||
],
|
],
|
||||||
comment: true,
|
comment: true,
|
||||||
flags: [{
|
flags: [TEST_FLAG],
|
||||||
adds: [],
|
|
||||||
name: 'foo',
|
|
||||||
priority: 1,
|
|
||||||
removes: [],
|
|
||||||
requires: [],
|
|
||||||
}],
|
|
||||||
name: '',
|
name: '',
|
||||||
remote: remoteConfig,
|
remote: remoteConfig,
|
||||||
states: [],
|
states: [],
|
||||||
|
@ -85,15 +111,7 @@ describe('project sync', () => {
|
||||||
project: {
|
project: {
|
||||||
colors: [],
|
colors: [],
|
||||||
comment: true,
|
comment: true,
|
||||||
flags: [{
|
flags: [TEST_FLAG],
|
||||||
adds: [],
|
|
||||||
color: '',
|
|
||||||
desc: '',
|
|
||||||
name: '',
|
|
||||||
priority: 1,
|
|
||||||
removes: [],
|
|
||||||
requires: [],
|
|
||||||
}],
|
|
||||||
name: '',
|
name: '',
|
||||||
remote: remoteConfig,
|
remote: remoteConfig,
|
||||||
states: [],
|
states: [],
|
||||||
|
@ -132,24 +150,7 @@ describe('project sync', () => {
|
||||||
flags: [],
|
flags: [],
|
||||||
name: '',
|
name: '',
|
||||||
remote: remoteConfig,
|
remote: remoteConfig,
|
||||||
states: [{
|
states: [TEST_STATE],
|
||||||
adds: [],
|
|
||||||
color: '',
|
|
||||||
desc: '',
|
|
||||||
divider: '/',
|
|
||||||
name: 'foo',
|
|
||||||
priority: 1,
|
|
||||||
removes: [],
|
|
||||||
requires: [],
|
|
||||||
values: [{
|
|
||||||
adds: [],
|
|
||||||
becomes: [],
|
|
||||||
name: 'bar',
|
|
||||||
priority: 1,
|
|
||||||
removes: [],
|
|
||||||
requires: [],
|
|
||||||
}],
|
|
||||||
}],
|
|
||||||
},
|
},
|
||||||
random: alea(),
|
random: alea(),
|
||||||
remote,
|
remote,
|
||||||
|
@ -217,4 +218,67 @@ describe('project sync', () => {
|
||||||
describe('create label', () => {
|
describe('create label', () => {
|
||||||
it('should create label');
|
it('should create label');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('update label', () => {
|
||||||
|
it('should update flags');
|
||||||
|
it('should update states', async () => {
|
||||||
|
const logger = NullLogger.global;
|
||||||
|
const remote = createStubInstance(GithubRemote);
|
||||||
|
|
||||||
|
await updateLabel({
|
||||||
|
logger,
|
||||||
|
project: {
|
||||||
|
colors: [],
|
||||||
|
comment: false,
|
||||||
|
flags: [],
|
||||||
|
name: '',
|
||||||
|
remote: {
|
||||||
|
data: {},
|
||||||
|
dryrun: false,
|
||||||
|
logger,
|
||||||
|
type: '',
|
||||||
|
},
|
||||||
|
states: [TEST_STATE],
|
||||||
|
},
|
||||||
|
random: alea(),
|
||||||
|
remote,
|
||||||
|
}, {
|
||||||
|
color: '',
|
||||||
|
desc: '',
|
||||||
|
name: 'foo/bar',
|
||||||
|
project: '',
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(remote.updateLabel).to.have.been.calledWithMatch({
|
||||||
|
name: 'foo/bar',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw on labels that do not exist', async () => {
|
||||||
|
const logger = NullLogger.global;
|
||||||
|
await expect(updateLabel({
|
||||||
|
logger,
|
||||||
|
project: {
|
||||||
|
colors: [],
|
||||||
|
comment: false,
|
||||||
|
flags: [],
|
||||||
|
name: '',
|
||||||
|
remote: {
|
||||||
|
data: {},
|
||||||
|
dryrun: false,
|
||||||
|
logger,
|
||||||
|
type: '',
|
||||||
|
},
|
||||||
|
states: [],
|
||||||
|
},
|
||||||
|
random: alea(),
|
||||||
|
remote: createStubInstance(GithubRemote),
|
||||||
|
}, {
|
||||||
|
color: '',
|
||||||
|
desc: '',
|
||||||
|
name: '',
|
||||||
|
project: '',
|
||||||
|
})).to.eventually.be.rejectedWith(InvalidArgumentError);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue