Skip to content

Commit 848f71f

Browse files
authored
:bowtie: Plugin generator (#174)
* initial asking * 🏗️ cleanup * plugin generator functioning * lint fix * conditional advanced features * small json error * start asking description * description prompt * added create tests * prep for testing * finish tests * add create plugin link to docs * add reference to plugin creator in docs * 📈 speed up cov from CI
1 parent ba463fd commit 848f71f

File tree

19 files changed

+302
-3
lines changed

19 files changed

+302
-3
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ script:
1010
- 'npm run test:ci'
1111
- yarn danger ci
1212
after_success:
13-
- './node_modules/.bin/jest --coverage && cat ./coverage/lcov.info | ./node_modules/.bin/codecov'
13+
- './node_modules/.bin/jest --coverage --runInBand && cat ./coverage/lcov.info | ./node_modules/.bin/codecov'
1414
notifications:
1515
webhooks:
1616
urls:

.vscode/cSpell.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
"infinite.red",
3232
"info",
3333
"macos",
34+
"namespacing",
3435
"newclear",
3536
"npmignore",
3637
"Plugin",
@@ -46,7 +47,8 @@
4647
"tada",
4748
"tempy",
4849
"updtr",
49-
"v1"
50+
"v1",
51+
"walkthrough"
5052
],
5153
// flagWords - list of words to be always considered incorrect
5254
// This is useful for offensive words and common spelling errors.

__tests__/__mocks__/mockContext.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ const mockContext = {
1717
system: {
1818
startTimer: jest.fn(() => jest.fn()),
1919
},
20+
template: {
21+
generate: jest.fn(),
22+
},
2023
print: {
2124
error: jest.fn(),
2225
success: jest.fn(),
@@ -33,19 +36,22 @@ const mockContext = {
3336
green: jest.fn(),
3437
red: jest.fn(),
3538
blue: jest.fn(),
39+
magenta: jest.fn(),
3640
},
3741
colors: {
3842
green: jest.fn(),
3943
red: jest.fn(),
4044
blue: jest.fn(),
45+
magenta: jest.fn(),
4146
},
4247
},
4348
printSeparator: jest.fn(),
4449
parameters: {
4550
options: {},
4651
},
4752
prompt: {
48-
ask: jest.fn(() => Promise.resolve({ createFile: true })),
53+
ask: jest.fn(({ name }) => Promise.resolve({ [name]: 'taco', createFile: true })),
54+
confirm: jest.fn(() => true)
4955
},
5056
solidarity: noConfigSolidarity,
5157
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`check result shape 1`] = `[Function]`;
4+
5+
exports[`investigate createPlugin 1`] = `
6+
Array [
7+
Array [
8+
".gitignore.ejs",
9+
".gitignore",
10+
],
11+
Array [
12+
"README.md.ejs",
13+
"README.md",
14+
],
15+
Array [
16+
"package.json.ejs",
17+
"package.json",
18+
],
19+
]
20+
`;
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
const createPlugin: Function = require('../../src/extensions/functions/createPlugin')
2+
const context = require('mockContext')
3+
4+
test('check result shape', () => {
5+
expect(createPlugin).toMatchSnapshot()
6+
})
7+
8+
test('investigate createPlugin', async () => {
9+
10+
const result = await createPlugin(context)
11+
expect(result).toMatchSnapshot()
12+
expect(context.template.generate).toBeCalled()
13+
expect(context.prompt.ask).toBeCalled()
14+
expect(context.prompt.confirm).toBeCalled()
15+
expect(context.print.success).toBeCalled()
16+
})
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`Snapshot create command 1`] = `
4+
Object {
5+
"alias": "c",
6+
"description": "Displays this help",
7+
"run": [Function],
8+
}
9+
`;

__tests__/commands/create.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import createCommand from '../../src/commands/create'
2+
const mockContext = require('mockContext')
3+
4+
test('Snapshot create command', () => {
5+
expect(createCommand).toMatchSnapshot()
6+
})
7+
8+
it('enforces required properties', () => {
9+
expect(createCommand.description).toBeTruthy()
10+
expect(createCommand.run).toBeTruthy()
11+
expect(typeof createCommand.run).toBe('function')
12+
})
13+
14+
test('check solidarity create with no parameter', async () => {
15+
const result = await createCommand.run(mockContext)
16+
expect(mockContext.print.error.mock.calls).toEqual([["Missing what to create"], ["solidarity create <wut?>"]])
17+
expect(mockContext.print.info.mock.calls.length).toBe(1)
18+
})
19+
20+
test('check solidarity create with plugin', async () => {
21+
const goodContext = {
22+
...mockContext,
23+
parameters: { first: 'plugin' },
24+
solidarity: { createPlugin: jest.fn() }
25+
}
26+
await createCommand.run(goodContext)
27+
expect(goodContext.solidarity.createPlugin).toBeCalled()
28+
29+
// now make it fail
30+
const errorString = 'ER MA GERD ARRAWRS'
31+
goodContext.solidarity.createPlugin = jest.fn(() => throw Error(errorString))
32+
await createCommand.run(goodContext)
33+
expect(goodContext.print.error.mock.calls.slice(-1).toString()).toEqual(`Error: ${errorString}`)
34+
})

__tests__/extensions/__snapshots__/extensionCheck.ts.snap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Object {
1010
"checkENV": [Function],
1111
"checkFile": [Function],
1212
"checkRequirement": [Function],
13+
"createPlugin": [Function],
1314
"getLineWithVersion": [Function],
1415
"getSolidaritySettings": [Function],
1516
"getVersion": [Function],

docs/plugins.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# Writing your own plugins
22
If you're using a technology that doesn't have a plugin, or if you'd just like build your own custom rules to use in solidarity, we've made creating plugins extremely simple.
33

4+
The following docs will show you all the features of how to create a plugin. If you'd like, you can generate a plugin-base by typing `solidarity create plugin`. This starts a walkthrough that will ask you questions to help you get started writing your plugin.
5+
46
## Plugin Docs
57
* [Write the Simplest Plugin](/docs/simplePlugin.md)
68
* [Plugins that write Solidarity Files from Code](/docs/solidarityFromCode.md)

src/commands/create.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { GluegunCommand } from 'gluegun'
2+
3+
const createables = ['plugin']
4+
5+
module.exports = {
6+
alias: 'c',
7+
description: 'Displays this help',
8+
run: async context => {
9+
const { print, solidarity, parameters } = context
10+
switch (parameters.first && parameters.first.toLowerCase()) {
11+
case 'plugin':
12+
// Handle errors like grown-ups
13+
try {
14+
await solidarity.createPlugin(context)
15+
} catch (e) {
16+
print.error(e)
17+
}
18+
break
19+
default:
20+
print.error('Missing what to create')
21+
print.error('solidarity create <wut?>')
22+
print.info(`Things you can create: ${createables}`)
23+
}
24+
},
25+
} as GluegunCommand

0 commit comments

Comments
 (0)