added tests for generated template files
Summary: Created a test that snapshots the generated files, so that we can capture accidental regressions when generating files. Also made the package id to package name a bit more robust Reviewed By: jknoxville Differential Revision: D21619633 fbshipit-source-id: 88ffb127e050d840df9ccd4b15ba29a71f341975
This commit is contained in:
committed by
Facebook GitHub Bot
parent
3f86c9f6d2
commit
49b4022228
@@ -47,7 +47,8 @@
|
|||||||
"postpack": "rimraf oclif.manifest.json",
|
"postpack": "rimraf oclif.manifest.json",
|
||||||
"prepack": "yarn reset && yarn build && oclif-dev manifest && oclif-dev readme",
|
"prepack": "yarn reset && yarn build && oclif-dev manifest && oclif-dev readme",
|
||||||
"run": "yarn build && bin/run",
|
"run": "yarn build && bin/run",
|
||||||
"version": "oclif-dev readme && hg add README.md"
|
"version": "oclif-dev readme && hg add README.md",
|
||||||
|
"test": "yarn jest"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8.0.0"
|
"node": ">=8.0.0"
|
||||||
|
|||||||
141
desktop/pkg/src/__tests__/runInit.node.ts
Normal file
141
desktop/pkg/src/__tests__/runInit.node.ts
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*
|
||||||
|
* @format
|
||||||
|
*/
|
||||||
|
|
||||||
|
import fse from 'fs-extra';
|
||||||
|
|
||||||
|
import {initTemplate} from '../commands/init';
|
||||||
|
|
||||||
|
let files: Record<string, string> = {};
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
function ensureDir() {
|
||||||
|
// no implementation
|
||||||
|
}
|
||||||
|
function writeFile(name: string, contents: string) {
|
||||||
|
files[name] = contents;
|
||||||
|
}
|
||||||
|
|
||||||
|
files = {};
|
||||||
|
jest.mock('fs-extra', () => jest.fn());
|
||||||
|
// @ts-ignore
|
||||||
|
fse.ensureDir = ensureDir;
|
||||||
|
// @ts-ignore
|
||||||
|
fse.writeFile = writeFile;
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
// @ts-ignore
|
||||||
|
// fse.ensureDir.mockRestore();
|
||||||
|
// @ts-ignore
|
||||||
|
// fs.writeFile.mockRestore();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('It generates the correct files', async () => {
|
||||||
|
await initTemplate('my weird Package %name. etc', 'Nice title', '/dev/null');
|
||||||
|
expect(files).toMatchInlineSnapshot(`
|
||||||
|
Object {
|
||||||
|
"/dev/null/.gitignore": "node_modules
|
||||||
|
dist/
|
||||||
|
",
|
||||||
|
"/dev/null/package.json": "{
|
||||||
|
\\"$schema\\": \\"https://fbflipper.com/schemas/plugin-package/v2.json\\",
|
||||||
|
\\"name\\": \\"flipper-plugin-my-weird-package-name-etc\\",
|
||||||
|
\\"id\\": \\"my weird Package %name. etc\\",
|
||||||
|
\\"version\\": \\"1.0.0\\",
|
||||||
|
\\"main\\": \\"dist/bundle.js\\",
|
||||||
|
\\"flipperBundlerEntry\\": \\"src/index.tsx\\",
|
||||||
|
\\"license\\": \\"MIT\\",
|
||||||
|
\\"keywords\\": [
|
||||||
|
\\"flipper-plugin\\"
|
||||||
|
],
|
||||||
|
\\"icon\\": \\"apps\\",
|
||||||
|
\\"title\\": \\"Nice title\\",
|
||||||
|
\\"scripts\\": {
|
||||||
|
\\"lint\\": \\"flipper-pkg lint\\",
|
||||||
|
\\"prepack\\": \\"flipper-pkg lint && flipper-pkg bundle\\",
|
||||||
|
\\"build\\": \\"flipper-pkg bundle\\",
|
||||||
|
\\"watch\\": \\"flipper-pkg bundle --watch\\"
|
||||||
|
},
|
||||||
|
\\"peerDependencies\\": {
|
||||||
|
\\"flipper\\": \\"latest\\"
|
||||||
|
},
|
||||||
|
\\"devDependencies\\": {
|
||||||
|
\\"@types/react\\": \\"latest\\",
|
||||||
|
\\"@types/react-dom\\": \\"latest\\",
|
||||||
|
\\"flipper\\": \\"latest\\",
|
||||||
|
\\"flipper-pkg\\": \\"latest\\"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"/dev/null/src/index.tsx": "import React from 'react';
|
||||||
|
import {FlipperPlugin, View, KeyboardActions} from 'flipper';
|
||||||
|
|
||||||
|
type State = {};
|
||||||
|
|
||||||
|
type Data = {};
|
||||||
|
|
||||||
|
type PersistedState = {
|
||||||
|
data: Array<Data>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default class extends FlipperPlugin<State, any, PersistedState> {
|
||||||
|
static keyboardActions: KeyboardActions = ['clear'];
|
||||||
|
|
||||||
|
static defaultPersistedState: PersistedState = {
|
||||||
|
data: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
static persistedStateReducer = (
|
||||||
|
persistedState: PersistedState,
|
||||||
|
method: string,
|
||||||
|
data: Data,
|
||||||
|
): PersistedState => {
|
||||||
|
return {
|
||||||
|
...persistedState,
|
||||||
|
data: persistedState.data.concat([data]),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
state = {};
|
||||||
|
|
||||||
|
onKeyboardAction = (action: string) => {
|
||||||
|
if (action === 'clear') {
|
||||||
|
this.props.setPersistedState({data: []});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<View scrollable>
|
||||||
|
{this.props.persistedState.data.map((d) => (
|
||||||
|
<div>{JSON.stringify(d, null, 2)}<hr/></div>
|
||||||
|
))}
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"/dev/null/tsconfig.json": "{
|
||||||
|
\\"compilerOptions\\": {
|
||||||
|
\\"target\\": \\"ES2017\\",
|
||||||
|
\\"module\\": \\"ES6\\",
|
||||||
|
\\"jsx\\": \\"react\\",
|
||||||
|
\\"sourceMap\\": true,
|
||||||
|
\\"noEmit\\": true,
|
||||||
|
\\"strict\\": true,
|
||||||
|
\\"moduleResolution\\": \\"node\\",
|
||||||
|
\\"esModuleInterop\\": true,
|
||||||
|
\\"forceConsistentCasingInFileNames\\": true
|
||||||
|
},
|
||||||
|
\\"files\\": [\\"src/index.tsx\\"]
|
||||||
|
}
|
||||||
|
",
|
||||||
|
}
|
||||||
|
`);
|
||||||
|
});
|
||||||
@@ -56,52 +56,61 @@ export default class Init extends Command {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
const pluginDirectory: string = path.resolve(process.cwd(), args.directory);
|
const pluginDirectory: string = path.resolve(process.cwd(), args.directory);
|
||||||
|
|
||||||
const title: string = (await inquirer.prompt(titleQuestion)).title;
|
const title: string = (await inquirer.prompt(titleQuestion)).title;
|
||||||
const packageNameSuffix = id.toLowerCase().replace(' ', '-');
|
const packageName = getPackageNameFromId(id);
|
||||||
const templateItems = await recursiveReaddir(templateDir);
|
const outputDirectory = path.join(pluginDirectory, packageName);
|
||||||
const outputDirectory = path.join(
|
|
||||||
pluginDirectory,
|
|
||||||
'flipper-plugin-' + packageNameSuffix,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (fs.existsSync(outputDirectory)) {
|
if (fs.existsSync(outputDirectory)) {
|
||||||
console.error(`Directory '${outputDirectory}' already exists`);
|
console.error(`Directory '${outputDirectory}' already exists`);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
await fs.ensureDir(outputDirectory);
|
|
||||||
|
|
||||||
console.log(
|
console.log(
|
||||||
`⚙️ Initializing Flipper desktop template in ${outputDirectory}`,
|
`⚙️ Initializing Flipper desktop template in ${outputDirectory}`,
|
||||||
);
|
);
|
||||||
|
await fs.ensureDir(outputDirectory);
|
||||||
|
initTemplate(id, title, outputDirectory);
|
||||||
|
|
||||||
for (const item of templateItems) {
|
console.log(`⚙️ Installing dependencies`);
|
||||||
const lstat = await fs.lstat(item);
|
|
||||||
if (lstat.isFile()) {
|
|
||||||
const file = path.relative(templateDir, item);
|
|
||||||
const dir = path.dirname(file);
|
|
||||||
const newDir = path.join(outputDirectory, dir);
|
|
||||||
const newFile = file.endsWith('.template')
|
|
||||||
? path.join(
|
|
||||||
outputDirectory,
|
|
||||||
file.substring(0, file.length - templateExt.length),
|
|
||||||
)
|
|
||||||
: path.join(outputDirectory, file);
|
|
||||||
await fs.ensureDir(newDir);
|
|
||||||
const content = (await fs.readFile(item))
|
|
||||||
.toString()
|
|
||||||
.replace('{{id}}', id)
|
|
||||||
.replace('{{title}}', title)
|
|
||||||
.replace('{{package_name_suffix}}', packageNameSuffix);
|
|
||||||
await fs.writeFile(newFile, content);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
spawnSync('yarn', ['install'], {cwd: outputDirectory, stdio: [0, 1, 2]});
|
spawnSync('yarn', ['install'], {cwd: outputDirectory, stdio: [0, 1, 2]});
|
||||||
|
|
||||||
console.log(
|
console.log(
|
||||||
`✅ Plugin directory initialized. Package name: flipper-plugin-${packageNameSuffix}.`,
|
`✅ Plugin directory initialized. Package name: ${packageName}.`,
|
||||||
);
|
|
||||||
console.log(
|
|
||||||
` Run 'cd flipper-plugin-${packageNameSuffix} && yarn watch' to get started!`,
|
|
||||||
);
|
);
|
||||||
|
console.log(` Run 'cd ${packageName} && yarn watch' to get started!`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPackageNameFromId(id: string): string {
|
||||||
|
return 'flipper-plugin-' + id.toLowerCase().replace(/[^a-zA-Z0-9\-_]+/g, '-');
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function initTemplate(
|
||||||
|
id: string,
|
||||||
|
title: string,
|
||||||
|
outputDirectory: string,
|
||||||
|
) {
|
||||||
|
const packageName = getPackageNameFromId(id);
|
||||||
|
const templateItems = await recursiveReaddir(templateDir);
|
||||||
|
|
||||||
|
for (const item of templateItems) {
|
||||||
|
const lstat = await fs.lstat(item);
|
||||||
|
if (lstat.isFile()) {
|
||||||
|
const file = path.relative(templateDir, item);
|
||||||
|
const dir = path.dirname(file);
|
||||||
|
const newDir = path.join(outputDirectory, dir);
|
||||||
|
const newFile = file.endsWith(templateExt)
|
||||||
|
? path.join(
|
||||||
|
outputDirectory,
|
||||||
|
file.substring(0, file.length - templateExt.length),
|
||||||
|
)
|
||||||
|
: path.join(outputDirectory, file);
|
||||||
|
await fs.ensureDir(newDir);
|
||||||
|
const content = (await fs.readFile(item))
|
||||||
|
.toString()
|
||||||
|
.replace('{{id}}', id)
|
||||||
|
.replace('{{title}}', title)
|
||||||
|
.replace('{{package_name}}', packageName);
|
||||||
|
await fs.writeFile(newFile, content);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://fbflipper.com/schemas/plugin-package/v2.json",
|
"$schema": "https://fbflipper.com/schemas/plugin-package/v2.json",
|
||||||
"name": "flipper-plugin-{{package_name_suffix}}",
|
"name": "{{package_name}}",
|
||||||
"id": "{{id}}",
|
"id": "{{id}}",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"main": "dist/bundle.js",
|
"main": "dist/bundle.js",
|
||||||
|
|||||||
Reference in New Issue
Block a user