diff --git a/__tests__/command_helpers/__snapshots__/getSolidaritySettings.ts.snap b/__tests__/command_helpers/__snapshots__/getSolidaritySettings.ts.snap index 212f2fd..a095f9a 100644 --- a/__tests__/command_helpers/__snapshots__/getSolidaritySettings.ts.snap +++ b/__tests__/command_helpers/__snapshots__/getSolidaritySettings.ts.snap @@ -1,3 +1,3 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`getSolidaritySettings w/ success getSolidaritySettings exists 1`] = `[Function]`; +exports[`basic getSolidaritySettings w/ success getSolidaritySettings exists 1`] = `[Function]`; diff --git a/__tests__/command_helpers/getSolidaritySettings.ts b/__tests__/command_helpers/getSolidaritySettings.ts index 5c09525..1b15d8c 100644 --- a/__tests__/command_helpers/getSolidaritySettings.ts +++ b/__tests__/command_helpers/getSolidaritySettings.ts @@ -1,19 +1,19 @@ import { solidarity } from '../../src' import getSolidaritySettings from '../../src/extensions/functions/getSolidaritySettings' -const context = require('gluegun/toolbox') +const context = require('mockContext') -describe('getSolidaritySettings', () => { +describe('basic getSolidaritySettings', () => { describe('w/ success', () => { test('getSolidaritySettings exists', () => expect(getSolidaritySettings).toMatchSnapshot()) - test('getSolidaritySettings succeeds', async () => { + test('getSolidaritySettings succeeds', () => { const resultSettings = getSolidaritySettings(context) // we got an object with requirements defined expect(resultSettings).toMatchObject({ requirements: {} }) }) - test('getSolidaritySettings succeeds', async () => { + test('getSolidaritySettings succeeds', () => { process.chdir('__tests__/sandbox/solidarity_json') const resultSettings = getSolidaritySettings(context) // we got an object with requirements defined @@ -22,19 +22,98 @@ describe('getSolidaritySettings', () => { }) }) - test('getSolidaritySettings can fail', async () => { + describe('w/ failure', () => { + test('getSolidaritySettings can fail', () => { + expect(() => { + process.chdir('__tests__') + const resultSettings = getSolidaritySettings(context) + }).toThrow() + process.chdir('../') + }) + + test('getSolidaritySettings can warn with missing requirements', () => { + expect(() => { + process.chdir('__tests__/sandbox/solidarity_broken') + const resultSettings = getSolidaritySettings(context) + }).toThrowError('ERROR: Found, but no requirements key. Please validate your solidarity file') + process.chdir('../../../') + }) + } +}) + +describe('parameterized getSolidaritySettings', () => { + + test('custom path with -f', () => { + context.parameters.options = { f: '__tests__/sandbox/solidarity_json' } + const resultSettings = getSolidaritySettings(context) + // we got an object with requirements defined + expect(resultSettings).toMatchObject({ requirements: {} }) + context.parameters.options = {} + }) + + test('custom path with --solidarityFile', () => { + context.parameters.options = { solidarityFile: '__tests__/sandbox/solidarity_json' } + const resultSettings = getSolidaritySettings(context) + // we got an object with requirements defined + expect(resultSettings).toMatchObject({ requirements: {} }) + context.parameters.options = {} + }) + + test('failing path message', () => { + // test longhand + context.parameters.options = { solidarityFile: '__tests__/fake' } expect(() => { - process.chdir('__tests__') const resultSettings = getSolidaritySettings(context) - }).toThrow() - process.chdir('../') + }).toThrowError('ERROR: There is no solidarity file at the given path') + // test shorthand + context.parameters.options = { f: '__tests__/fake' } + expect(() => { + const resultSettings = getSolidaritySettings(context) + }).toThrowError('ERROR: There is no solidarity file at the given path') + context.parameters.options = {} }) - test('getSolidaritySettings can warn with missing requirements', async () => { - expect(() => { - process.chdir('__tests__/sandbox/solidarity_broken') + describe('custom module tests', () => { + beforeAll(() => { + process.chdir('__tests__/sandbox/fake_project') + }) + + test('can find solidarity file in module with flag -m', () => { + context.parameters.options = { m: 'mock_module' } + const resultSettings = getSolidaritySettings(context) + // we got an object with requirements defined + expect(resultSettings).toMatchObject({ requirements: {} }) + context.parameters.options = {} + }) + + test('can find solidarity file in module with flag --module', () => { + context.parameters.options = { module: 'mock_module' } const resultSettings = getSolidaritySettings(context) - }).toThrowError('ERROR: Found, but no requirements key. Please validate your solidarity file') - process.chdir('../../../') + // we got an object with requirements defined + expect(resultSettings).toMatchObject({ requirements: {} }) + context.parameters.options = {} + }) + + test('can find solidarity JSON file in module with flag --module', () => { + context.parameters.options = { module: 'mock_second_module' } + const resultSettings = getSolidaritySettings(context) + // we got an object with requirements defined + expect(resultSettings).toMatchObject({ requirements: {} }) + context.parameters.options = {} + }) + + test('errors if no solidarity file in module', () => { + context.parameters.options = { module: 'nope' } + expect(() => { + const resultSettings = getSolidaritySettings(context) + }).toThrowError('ERROR: There is no solidarity file found with the given module') + context.parameters.options = {} + }) + + afterAll(() => { + process.chdir('../../../') + }) + }) + }) diff --git a/__tests__/commands/help.ts b/__tests__/commands/help.ts index a62cb58..ab901bf 100644 --- a/__tests__/commands/help.ts +++ b/__tests__/commands/help.ts @@ -27,7 +27,7 @@ test('Calls print items several times', () => { expect(context.print.success.mock.calls.length).toBe(0) expect(context.print.colors.magenta.mock.calls.length).toBe(0) helpCommand.run(context) - expect(context.print.info.mock.calls.length).toBe(6) + expect(context.print.info.mock.calls.length).toBe(8) expect(context.print.printCommands.mock.calls.length).toBe(1) expect(context.print.success.mock.calls.length).toBe(2) expect(context.print.colors.magenta.mock.calls.length).toBe(2) diff --git a/__tests__/sandbox/fake_project/node_modules/mock_module/.solidarity b/__tests__/sandbox/fake_project/node_modules/mock_module/.solidarity new file mode 100644 index 0000000..c132fe1 --- /dev/null +++ b/__tests__/sandbox/fake_project/node_modules/mock_module/.solidarity @@ -0,0 +1,6 @@ +{ + "requirements": { + "NPM": [{ "rule": "cli", "binary": "npm" }], + "Node": [{ "rule": "cli", "binary": "node", "semver": ">=4.6.0", "error": "Upgrade to latest node >= 4.6 please."}] + } +} diff --git a/__tests__/sandbox/fake_project/node_modules/mock_second_module/.solidarity.json b/__tests__/sandbox/fake_project/node_modules/mock_second_module/.solidarity.json new file mode 100644 index 0000000..c132fe1 --- /dev/null +++ b/__tests__/sandbox/fake_project/node_modules/mock_second_module/.solidarity.json @@ -0,0 +1,6 @@ +{ + "requirements": { + "NPM": [{ "rule": "cli", "binary": "npm" }], + "Node": [{ "rule": "cli", "binary": "node", "semver": ">=4.6.0", "error": "Upgrade to latest node >= 4.6 please."}] + } +} diff --git a/src/commands/help.ts b/src/commands/help.ts index 5268613..6ec85a8 100644 --- a/src/commands/help.ts +++ b/src/commands/help.ts @@ -13,6 +13,8 @@ module.exports = { print.info(' --verbose\t (-a) Prints all detected info during solidarity check') print.info(' --moderate\t (-m) Prints failures in check or single success message') print.info(' --silent\t (-s) No output, just a return code of success/failure') + print.info(' --solidarityFile\t (-f) Use given path to solidarity file for settings') + print.info(' --module\t (-m) Search for a solidarity file in the given npm package') print.success(colors.magenta('\nSolidarity is open source - https://github.com/infinitered/solidarity')) print.info(colors.magenta('If you need additional help, join our Slack at http://community.infinite.red')) diff --git a/src/extensions/functions/getSolidaritySettings.ts b/src/extensions/functions/getSolidaritySettings.ts index 995bf5b..606cc76 100644 --- a/src/extensions/functions/getSolidaritySettings.ts +++ b/src/extensions/functions/getSolidaritySettings.ts @@ -1,11 +1,39 @@ import { SolidarityRunContext, SolidaritySettings } from '../../types' import * as JSON5 from 'json5' +import * as path from 'path' + module.exports = (context: SolidarityRunContext): SolidaritySettings => { - const { filesystem } = context + const { filesystem, parameters } = context + const options = parameters.options || {} // fix possibly undefined from gluegun - // for now only JSON and JSON5 support + /* for now only JSON and JSON5 support + * Summary: + * Looks for `.solidarity` or `.solidarity.json` files + * Unless you pass parameter options telling us to look + * in specific paths or node modules + */ let solidaritySettings - if (filesystem.exists('.solidarity')) { + if (options.solidarityFile || options.f) { + // They are telling us where to go + const filePath = options.solidarityFile || options.f + if (filesystem.exists(filePath)) { + solidaritySettings = JSON5.parse(filesystem.read('.solidarity')) + } else { + throw 'ERROR: There is no solidarity file at the given path' + } + } else if (options.module || options.m) { + // We will search that module + const moduleName = options.module || options.m + const filePath = path.join('node_modules', moduleName, '.solidarity') + + if (filesystem.exists(filePath)) { + solidaritySettings = JSON5.parse(filesystem.read(filePath)) + } else if (filesystem.exists(filePath + '.json')) { + solidaritySettings = JSON5.parse(filesystem.read(filePath + '.json')) + } else { + throw 'ERROR: There is no solidarity file found with the given module' + } + } else if (filesystem.exists('.solidarity')) { solidaritySettings = JSON5.parse(filesystem.read('.solidarity')) } else if (filesystem.exists('.solidarity.json')) { solidaritySettings = JSON5.parse(filesystem.read('.solidarity.json'))