1
0
Fork 0

fix(test): cover config loading, graph styles

This commit is contained in:
ssube 2020-08-30 22:41:48 -05:00
parent 98391a9a47
commit 0ea5791a8f
Signed by: ssube
GPG Key ID: 3EED7B957D362AF1
4 changed files with 182 additions and 59 deletions

View File

@ -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,
};

View File

@ -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=');
}
}); });
}); });

View File

@ -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);
});
}); });
}); });

View File

@ -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);
});
});
}); });