diff --git a/src/config/index.ts b/src/config/index.ts index 39ecbb1..6a0336f 100644 --- a/src/config/index.ts +++ b/src/config/index.ts @@ -1,9 +1,8 @@ -import { InvalidArgumentError } from '@apextoaster/js-utils'; -import { createSchema } from '@apextoaster/js-yaml-schema'; -import { createConfig, loadFile } from '@apextoaster/js-config'; +import { createConfig } from '@apextoaster/js-config'; +import { IncludeOptions } from '@apextoaster/js-yaml-schema'; import Ajv from 'ajv'; 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 { join } from 'path'; @@ -63,16 +62,8 @@ export const CONFIG_SCHEMA_KEY = 'cautious-journey#/definitions/config'; /** * Load the config from files. */ -export async function initConfig(path: string): Promise { - const include = { - exists: existsSync, - join, - read: readFileSync, - resolve: realpathSync, - schema: DEFAULT_SAFE_SCHEMA, - }; - - const validator = new Ajv(SCHEMA_OPTIONS); +export async function initConfig(path: string, include = SCHEMA_OPTIONS): Promise { + const validator = new Ajv(AJV_OPTIONS); validator.addSchema(SCHEMA_DATA, 'cautious-journey'); const config = createConfig({ @@ -95,7 +86,7 @@ export async function initConfig(path: string): Promise { return config.getData(); } -export const SCHEMA_OPTIONS: Ajv.Options = { +export const AJV_OPTIONS: Ajv.Options = { allErrors: true, coerceTypes: 'array', missingRefs: 'fail', @@ -104,3 +95,11 @@ export const SCHEMA_OPTIONS: Ajv.Options = { useDefaults: true, verbose: true, }; + +export const SCHEMA_OPTIONS: IncludeOptions = { + exists: existsSync, + join, + read: readFileSync, + resolve: realpathSync, + schema: DEFAULT_SAFE_SCHEMA, +}; diff --git a/test/TestGraph.ts b/test/TestGraph.ts index 30d21e6..eaa47f3 100644 --- a/test/TestGraph.ts +++ b/test/TestGraph.ts @@ -126,12 +126,20 @@ describe('graph tools', () => { describe('edge style', () => { it('should color edges', () => { - expect(edgeStyle({ - source: 'foo', - target: 'bar', - type: EdgeType.BOTH, - verb: ChangeVerb.CREATED, - })).to.include('color='); + for (const verb of [ + ChangeVerb.BECAME, + ChangeVerb.CONFLICTED, + ChangeVerb.CREATED, + ChangeVerb.REMOVED, + ChangeVerb.REQUIRED, + ]) { + expect(edgeStyle({ + source: 'foo', + target: 'bar', + type: EdgeType.BOTH, + verb, + })).to.include('color='); + } }); }); diff --git a/test/config/TestConfig.ts b/test/config/TestConfig.ts index 17a1141..3c94fba 100644 --- a/test/config/TestConfig.ts +++ b/test/config/TestConfig.ts @@ -1,8 +1,60 @@ +import { IncludeOptions } from '@apextoaster/js-yaml-schema'; import { expect } from 'chai'; +import { DEFAULT_SAFE_SCHEMA } from 'js-yaml'; +import { match, stub } from 'sinon'; + +import { initConfig } from '../../src/config'; describe('config', () => { describe('init config', () => { - it('should load a valid config'); - it('should throw on invalid config'); + it('should load a valid config', async () => { + 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); + }); }); }); diff --git a/test/sync/TestSyncProjects.ts b/test/sync/TestSyncProjects.ts index 670fde0..a4c5ad4 100644 --- a/test/sync/TestSyncProjects.ts +++ b/test/sync/TestSyncProjects.ts @@ -1,11 +1,43 @@ +import { InvalidArgumentError } from '@apextoaster/js-utils'; import { expect } from 'chai'; -import { Container } from 'noicejs'; +import { Container, NullLogger } from 'noicejs'; import { alea } from 'seedrandom'; -import { match, spy, stub } from 'sinon'; +import { createStubInstance, match, spy, stub } from 'sinon'; import { BunyanLogger } from '../../src/logger/bunyan'; import { GithubRemote } from '../../src/remote/github'; 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('all labels', () => { @@ -33,13 +65,7 @@ describe('project sync', () => { 'ff0000', ], comment: true, - flags: [{ - adds: [], - name: 'foo', - priority: 1, - removes: [], - requires: [], - }], + flags: [TEST_FLAG], name: '', remote: remoteConfig, states: [], @@ -85,15 +111,7 @@ describe('project sync', () => { project: { colors: [], comment: true, - flags: [{ - adds: [], - color: '', - desc: '', - name: '', - priority: 1, - removes: [], - requires: [], - }], + flags: [TEST_FLAG], name: '', remote: remoteConfig, states: [], @@ -132,24 +150,7 @@ describe('project sync', () => { flags: [], name: '', remote: remoteConfig, - states: [{ - adds: [], - color: '', - desc: '', - divider: '/', - name: 'foo', - priority: 1, - removes: [], - requires: [], - values: [{ - adds: [], - becomes: [], - name: 'bar', - priority: 1, - removes: [], - requires: [], - }], - }], + states: [TEST_STATE], }, random: alea(), remote, @@ -217,4 +218,67 @@ describe('project sync', () => { describe('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); + }); + }); });