From 9ce6453d580227a7612aabf4ee4625cb12435fb1 Mon Sep 17 00:00:00 2001 From: Peter Halliday Date: Tue, 28 Feb 2017 01:21:09 +0100 Subject: [PATCH] basic CLI stuff --- .eslintrc.js | 1 + .gitignore | 1 + README.md | 2 +- bin/index.js | 3 ++ bin/init.js | 3 ++ lib/cli/generate.js | 63 ++++++++++++++++++++++++++++ lib/cli/init.js | 39 +++++++++++++++++ lib/constants.js | 11 +++++ lib/firegen/generate.js | 47 +++++++++++++++++++++ lib/firegen/index.js | 25 +++++++++++ lib/firegen/init/config.js | 62 +++++++++++++++++++++++++++ lib/firegen/init/entry.js | 58 ++++++++++++++++++++++++++ lib/firegen/init/index.js | 61 +++++++++++++++++++++++++++ lib/index.js | 9 ++-- package.json | 13 +++++- src/cli/generate.js | 24 +++++++++++ src/cli/init.js | 10 +++++ src/constants.js | 6 +++ src/firegen/generate.js | 15 +++++++ src/firegen/index.js | 2 + src/firegen/init/config.js | 23 ++++++++++ src/firegen/init/entry.js | 19 +++++++++ src/firegen/init/index.js | 30 +++++++++++++ src/index.js | 10 ++++- test/helpers/loader.js | 13 ++++++ test/helpers/setup.js | 11 +++++ test/helpers/temp-dir.js | 18 ++++++++ test/mocha.opts | 2 + test/src/cli/generate.js | 43 +++++++++++++++++++ test/src/cli/init.js | 21 ++++++++++ test/src/firegen/generate.js | 74 +++++++++++++++++++++++++++++++++ test/src/firegen/index.js | 10 +++++ test/src/firegen/init/config.js | 56 +++++++++++++++++++++++++ test/src/firegen/init/entry.js | 37 +++++++++++++++++ test/src/firegen/init/index.js | 54 ++++++++++++++++++++++++ test/src/index.js | 11 ++--- 36 files changed, 872 insertions(+), 15 deletions(-) create mode 100644 bin/index.js create mode 100644 bin/init.js create mode 100644 lib/cli/generate.js create mode 100644 lib/cli/init.js create mode 100644 lib/constants.js create mode 100644 lib/firegen/generate.js create mode 100644 lib/firegen/index.js create mode 100644 lib/firegen/init/config.js create mode 100644 lib/firegen/init/entry.js create mode 100644 lib/firegen/init/index.js create mode 100644 src/cli/generate.js create mode 100644 src/cli/init.js create mode 100644 src/constants.js create mode 100644 src/firegen/generate.js create mode 100644 src/firegen/index.js create mode 100644 src/firegen/init/config.js create mode 100644 src/firegen/init/entry.js create mode 100644 src/firegen/init/index.js create mode 100644 test/helpers/loader.js create mode 100644 test/helpers/setup.js create mode 100644 test/helpers/temp-dir.js create mode 100644 test/src/cli/generate.js create mode 100644 test/src/cli/init.js create mode 100644 test/src/firegen/generate.js create mode 100644 test/src/firegen/index.js create mode 100644 test/src/firegen/init/config.js create mode 100644 test/src/firegen/init/entry.js create mode 100644 test/src/firegen/init/index.js diff --git a/.eslintrc.js b/.eslintrc.js index 3f6befc..5330dbf 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -9,6 +9,7 @@ module.exports = { 'require-jsdoc': 0 }, parserOptions: { + ecmaVersion: 8, sourceType: 'module' } }; diff --git a/.gitignore b/.gitignore index addef67..20455f6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +/.temp/ /.alarmist/ /npm-debug.log /node_modules/ diff --git a/README.md b/README.md index 3c57f48..141e6aa 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ npm install --save-dev firegen Initialise an API definition file and config file ``` -./node_modules/.bin/firegen init +./node_modules/.bin/firegen-init ``` Using the defaults this will create the following files and directories diff --git a/bin/index.js b/bin/index.js new file mode 100644 index 0000000..a5aee79 --- /dev/null +++ b/bin/index.js @@ -0,0 +1,3 @@ +#!/usr/bin/env node +require('babel-polyfill'); +require('../lib/cli/generate')(process.argv.slice(2)); diff --git a/bin/init.js b/bin/init.js new file mode 100644 index 0000000..e334b94 --- /dev/null +++ b/bin/init.js @@ -0,0 +1,3 @@ +#!/usr/bin/env node +require('babel-polyfill'); +require('../lib/cli/init')(process.argv.slice(2)); diff --git a/lib/cli/generate.js b/lib/cli/generate.js new file mode 100644 index 0000000..537b830 --- /dev/null +++ b/lib/cli/generate.js @@ -0,0 +1,63 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var generate = function () { + var _ref = _asyncToGenerator(regeneratorRuntime.mark(function _callee() { + var preadFile, configJson; + return regeneratorRuntime.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + preadFile = (0, _es6Promisify2.default)(_fs2.default.readFile); + _context.next = 3; + return preadFile(configFile); + + case 3: + configJson = _context.sent; + _context.next = 6; + return _2.default.generate({ + root: _constants.DEFAULT_ROOT, + config: JSON.parse(configJson) + }); + + case 6: + case 'end': + return _context.stop(); + } + } + }, _callee, this); + })); + + return function generate() { + return _ref.apply(this, arguments); + }; +}(); + +var _ = require('../'); + +var _2 = _interopRequireDefault(_); + +var _path = require('path'); + +var _path2 = _interopRequireDefault(_path); + +var _fs = require('fs'); + +var _fs2 = _interopRequireDefault(_fs); + +var _es6Promisify = require('es6-promisify'); + +var _es6Promisify2 = _interopRequireDefault(_es6Promisify); + +var _constants = require('../constants'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } + +var configFile = _path2.default.join(_constants.DEFAULT_ROOT, _constants.CONFIG_FILE); + +exports.default = generate; \ No newline at end of file diff --git a/lib/cli/init.js b/lib/cli/init.js new file mode 100644 index 0000000..6aca0ff --- /dev/null +++ b/lib/cli/init.js @@ -0,0 +1,39 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var init = function () { + var _ref = _asyncToGenerator(regeneratorRuntime.mark(function _callee() { + return regeneratorRuntime.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + _context.next = 2; + return _2.default.init(_constants.DEFAULT_ROOT); + + case 2: + case 'end': + return _context.stop(); + } + } + }, _callee, this); + })); + + return function init() { + return _ref.apply(this, arguments); + }; +}(); + +var _ = require('../'); + +var _2 = _interopRequireDefault(_); + +var _constants = require('../constants'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } + +exports.default = init; \ No newline at end of file diff --git a/lib/constants.js b/lib/constants.js new file mode 100644 index 0000000..64c33d1 --- /dev/null +++ b/lib/constants.js @@ -0,0 +1,11 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +var DEFAULT_ROOT = exports.DEFAULT_ROOT = '.'; +var CONFIG_FILE = exports.CONFIG_FILE = '.firegen.json'; +var DEFAULT_ENTRY = exports.DEFAULT_ENTRY = 'api/src/index.js'; +var DEFAULT_API = exports.DEFAULT_API = 'api/lib/index.js'; +var DEFAULT_DATABASE = exports.DEFAULT_DATABASE = 'api/rules/database.rules.bolt'; +var DEFAULT_STORAGE = exports.DEFAULT_STORAGE = 'api/rules/storage.rules'; \ No newline at end of file diff --git a/lib/firegen/generate.js b/lib/firegen/generate.js new file mode 100644 index 0000000..47f8157 --- /dev/null +++ b/lib/firegen/generate.js @@ -0,0 +1,47 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var generate = function () { + var _ref2 = _asyncToGenerator(regeneratorRuntime.mark(function _callee(_ref) { + var root = _ref.root, + config = _ref.config; + return regeneratorRuntime.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + _context.next = 2; + return Promise.all([pwriteFile(_path2.default.resolve(root, config.output.api), ''), pwriteFile(_path2.default.resolve(root, config.output.database), ''), pwriteFile(_path2.default.resolve(root, config.output.storage), '')]); + + case 2: + case 'end': + return _context.stop(); + } + } + }, _callee, this); + })); + + return function generate(_x) { + return _ref2.apply(this, arguments); + }; +}(); + +var _path = require('path'); + +var _path2 = _interopRequireDefault(_path); + +var _fs = require('fs'); + +var _es6Promisify = require('es6-promisify'); + +var _es6Promisify2 = _interopRequireDefault(_es6Promisify); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } + +var pwriteFile = (0, _es6Promisify2.default)(_fs.writeFile); + +exports.default = generate; \ No newline at end of file diff --git a/lib/firegen/index.js b/lib/firegen/index.js new file mode 100644 index 0000000..4b52110 --- /dev/null +++ b/lib/firegen/index.js @@ -0,0 +1,25 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _init = require('./init'); + +Object.defineProperty(exports, 'init', { + enumerable: true, + get: function get() { + return _interopRequireDefault(_init).default; + } +}); + +var _generate = require('./generate'); + +Object.defineProperty(exports, 'generate', { + enumerable: true, + get: function get() { + return _interopRequireDefault(_generate).default; + } +}); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } \ No newline at end of file diff --git a/lib/firegen/init/config.js b/lib/firegen/init/config.js new file mode 100644 index 0000000..36bf7a1 --- /dev/null +++ b/lib/firegen/init/config.js @@ -0,0 +1,62 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.create = undefined; + +var create = function () { + var _ref2 = _asyncToGenerator(regeneratorRuntime.mark(function _callee(_ref) { + var root = _ref.root, + config = _ref.config; + var configFile, dirname; + return regeneratorRuntime.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + configFile = _path2.default.join(root, _constants.CONFIG_FILE); + dirname = _path2.default.dirname(configFile); + _context.next = 4; + return pmkdirp(dirname); + + case 4: + _context.next = 6; + return pwriteFile(configFile, JSON.stringify(config, null, 2)); + + case 6: + case 'end': + return _context.stop(); + } + } + }, _callee, this); + })); + + return function create(_x) { + return _ref2.apply(this, arguments); + }; +}(); + +var _fs = require('fs'); + +var _mkdirp = require('mkdirp'); + +var _mkdirp2 = _interopRequireDefault(_mkdirp); + +var _es6Promisify = require('es6-promisify'); + +var _es6Promisify2 = _interopRequireDefault(_es6Promisify); + +var _path = require('path'); + +var _path2 = _interopRequireDefault(_path); + +var _constants = require('../../constants'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } + +var pmkdirp = (0, _es6Promisify2.default)(_mkdirp2.default); +var pwriteFile = (0, _es6Promisify2.default)(_fs.writeFile); + +exports.create = create; \ No newline at end of file diff --git a/lib/firegen/init/entry.js b/lib/firegen/init/entry.js new file mode 100644 index 0000000..500ee32 --- /dev/null +++ b/lib/firegen/init/entry.js @@ -0,0 +1,58 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.create = undefined; + +var create = function () { + var _ref2 = _asyncToGenerator(regeneratorRuntime.mark(function _callee(_ref) { + var file = _ref.file; + var dirname; + return regeneratorRuntime.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + dirname = _path2.default.dirname(file); + _context.next = 3; + return pmkdirp(dirname); + + case 3: + _context.next = 5; + return pwriteFile(file, 'api.add(\'my first api\')\n'); + + case 5: + case 'end': + return _context.stop(); + } + } + }, _callee, this); + })); + + return function create(_x) { + return _ref2.apply(this, arguments); + }; +}(); + +var _fs = require('fs'); + +var _mkdirp = require('mkdirp'); + +var _mkdirp2 = _interopRequireDefault(_mkdirp); + +var _es6Promisify = require('es6-promisify'); + +var _es6Promisify2 = _interopRequireDefault(_es6Promisify); + +var _path = require('path'); + +var _path2 = _interopRequireDefault(_path); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } + +var pmkdirp = (0, _es6Promisify2.default)(_mkdirp2.default); +var pwriteFile = (0, _es6Promisify2.default)(_fs.writeFile); + +exports.create = create; \ No newline at end of file diff --git a/lib/firegen/init/index.js b/lib/firegen/init/index.js new file mode 100644 index 0000000..1a7c0cb --- /dev/null +++ b/lib/firegen/init/index.js @@ -0,0 +1,61 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var init = function () { + var _ref = _asyncToGenerator(regeneratorRuntime.mark(function _callee(root) { + return regeneratorRuntime.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + _context.next = 2; + return Promise.all([config.create({ + root: root, + config: { + entry: _constants.DEFAULT_ENTRY, + output: { + api: _constants.DEFAULT_API, + database: _constants.DEFAULT_DATABASE, + storage: _constants.DEFAULT_STORAGE + } + } + }), entry.create({ + file: _path2.default.join(root, _constants.DEFAULT_ENTRY) + })]); + + case 2: + case 'end': + return _context.stop(); + } + } + }, _callee, this); + })); + + return function init(_x) { + return _ref.apply(this, arguments); + }; +}(); + +var _config = require('./config'); + +var config = _interopRequireWildcard(_config); + +var _entry = require('./entry'); + +var entry = _interopRequireWildcard(_entry); + +var _path = require('path'); + +var _path2 = _interopRequireDefault(_path); + +var _constants = require('../../constants'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } + +function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } + +exports.default = init; \ No newline at end of file diff --git a/lib/index.js b/lib/index.js index a1719cf..4b6e23b 100644 --- a/lib/index.js +++ b/lib/index.js @@ -4,8 +4,9 @@ Object.defineProperty(exports, "__esModule", { value: true }); -exports.default = function () { - return 'hello world'; -}; +var _firegen = require('./firegen'); -; \ No newline at end of file +exports.default = { + init: _firegen.init, + generate: _firegen.generate +}; \ No newline at end of file diff --git a/package.json b/package.json index d98d0ad..2854ea3 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,10 @@ "name": "firegen", "version": "1.0.0", "description": "Generate database rules and JavaScript APIs for Firebase projects", + "bin": { + "firegen-init": "bin/init.js", + "firegen": "bin/index.js" + }, "main": "lib/index.js", "scripts": { "cmd:lint": "eslint .", @@ -34,6 +38,11 @@ "url": "https://github.com/pghalliday/firegen/issues" }, "homepage": "https://github.com/pghalliday/firegen#readme", + "dependencies": { + "babel-polyfill": "^6.23.0", + "es6-promisify": "^5.0.0", + "mkdirp": "^0.5.1" + }, "devDependencies": { "alarmist": "^1.0.4", "babel-cli": "^6.22.2", @@ -48,6 +57,8 @@ "mocha": "^3.2.0", "npm-run-all": "^4.0.1", "nyc": "^10.1.2", - "rimraf": "^2.6.1" + "rimraf": "^2.6.1", + "sinon": "^1.17.7", + "sinon-chai": "^2.8.0" } } diff --git a/src/cli/generate.js b/src/cli/generate.js new file mode 100644 index 0000000..94b68e6 --- /dev/null +++ b/src/cli/generate.js @@ -0,0 +1,24 @@ +import firegen from '../'; +import path from 'path'; +import fs from 'fs'; +import promisify from 'es6-promisify'; +import { + DEFAULT_ROOT, + CONFIG_FILE, +} from '../constants'; + +const configFile = path.join( + DEFAULT_ROOT, + CONFIG_FILE, +); + +async function generate() { + const preadFile = promisify(fs.readFile); + const configJson = await preadFile(configFile); + await firegen.generate({ + root: DEFAULT_ROOT, + config: JSON.parse(configJson), + }); +} + +export default generate; diff --git a/src/cli/init.js b/src/cli/init.js new file mode 100644 index 0000000..7f7afcf --- /dev/null +++ b/src/cli/init.js @@ -0,0 +1,10 @@ +import firegen from '../'; +import { + DEFAULT_ROOT, +} from '../constants'; + +async function init() { + await firegen.init(DEFAULT_ROOT); +} + +export default init; diff --git a/src/constants.js b/src/constants.js new file mode 100644 index 0000000..df6249a --- /dev/null +++ b/src/constants.js @@ -0,0 +1,6 @@ +export const DEFAULT_ROOT = '.'; +export const CONFIG_FILE = '.firegen.json'; +export const DEFAULT_ENTRY = 'api/src/index.js'; +export const DEFAULT_API = 'api/lib/index.js'; +export const DEFAULT_DATABASE = 'api/rules/database.rules.bolt'; +export const DEFAULT_STORAGE = 'api/rules/storage.rules'; diff --git a/src/firegen/generate.js b/src/firegen/generate.js new file mode 100644 index 0000000..9b4755c --- /dev/null +++ b/src/firegen/generate.js @@ -0,0 +1,15 @@ +import path from 'path'; +import {writeFile} from 'fs'; +import promisify from 'es6-promisify'; + +const pwriteFile = promisify(writeFile); + +async function generate({root, config}) { + await Promise.all([ + pwriteFile(path.resolve(root, config.output.api), ''), + pwriteFile(path.resolve(root, config.output.database), ''), + pwriteFile(path.resolve(root, config.output.storage), ''), + ]); +} + +export default generate; diff --git a/src/firegen/index.js b/src/firegen/index.js new file mode 100644 index 0000000..33bf905 --- /dev/null +++ b/src/firegen/index.js @@ -0,0 +1,2 @@ +export {default as init} from './init'; +export {default as generate} from './generate'; diff --git a/src/firegen/init/config.js b/src/firegen/init/config.js new file mode 100644 index 0000000..dddbbdb --- /dev/null +++ b/src/firegen/init/config.js @@ -0,0 +1,23 @@ +import { + writeFile, +} from 'fs'; +import mkdirp from 'mkdirp'; +import promisify from 'es6-promisify'; +import path from 'path'; +import { + CONFIG_FILE, +} from '../../constants'; + +const pmkdirp = promisify(mkdirp); +const pwriteFile = promisify(writeFile); + +async function create({root, config}) { + const configFile = path.join(root, CONFIG_FILE); + const dirname = path.dirname(configFile); + await pmkdirp(dirname); + await pwriteFile(configFile, JSON.stringify(config, null, 2)); +} + +export { + create, +}; diff --git a/src/firegen/init/entry.js b/src/firegen/init/entry.js new file mode 100644 index 0000000..f066d9e --- /dev/null +++ b/src/firegen/init/entry.js @@ -0,0 +1,19 @@ +import { + writeFile, +} from 'fs'; +import mkdirp from 'mkdirp'; +import promisify from 'es6-promisify'; +import path from 'path'; + +const pmkdirp = promisify(mkdirp); +const pwriteFile = promisify(writeFile); + +async function create({file}) { + const dirname = path.dirname(file); + await pmkdirp(dirname); + await pwriteFile(file, 'api.add(\'my first api\')\n'); +} + +export { + create, +}; diff --git a/src/firegen/init/index.js b/src/firegen/init/index.js new file mode 100644 index 0000000..aa9f572 --- /dev/null +++ b/src/firegen/init/index.js @@ -0,0 +1,30 @@ +import * as config from './config'; +import * as entry from './entry'; +import path from 'path'; +import { + DEFAULT_ENTRY, + DEFAULT_API, + DEFAULT_DATABASE, + DEFAULT_STORAGE, +} from '../../constants'; + +async function init(root) { + await Promise.all([ + config.create({ + root, + config: { + entry: DEFAULT_ENTRY, + output: { + api: DEFAULT_API, + database: DEFAULT_DATABASE, + storage: DEFAULT_STORAGE, + }, + }, + }), + entry.create({ + file: path.join(root, DEFAULT_ENTRY), + }), + ]); +} + +export default init; diff --git a/src/index.js b/src/index.js index d4bd59a..e21d46f 100644 --- a/src/index.js +++ b/src/index.js @@ -1,3 +1,9 @@ -export default function() { - return 'hello world'; +import { + init, + generate, +} from './firegen'; + +export default { + init, + generate, }; diff --git a/test/helpers/loader.js b/test/helpers/loader.js new file mode 100644 index 0000000..430de2d --- /dev/null +++ b/test/helpers/loader.js @@ -0,0 +1,13 @@ +import { + readFile, +} from 'fs'; +import promisify from 'es6-promisify'; + +const preadFile = promisify(readFile); + +async function loader(file, argNames, args) { + const body = await preadFile(file); + (new Function(...argNames, body))(...args); +}; + +export default loader; diff --git a/test/helpers/setup.js b/test/helpers/setup.js new file mode 100644 index 0000000..3ec99a6 --- /dev/null +++ b/test/helpers/setup.js @@ -0,0 +1,11 @@ +// polyfills +import 'babel-polyfill'; + +// common assertions +import sinon from 'sinon'; +import sinonChai from 'sinon-chai'; +import chai from 'chai'; +chai.should(); +chai.use(sinonChai); +global.expect = chai.expect; +global.sinon = sinon; diff --git a/test/helpers/temp-dir.js b/test/helpers/temp-dir.js new file mode 100644 index 0000000..cd800a9 --- /dev/null +++ b/test/helpers/temp-dir.js @@ -0,0 +1,18 @@ +import promisify from 'es6-promisify'; +import rimraf from 'rimraf'; +import mkdirp from 'mkdirp'; + +const primraf = promisify(rimraf); +const pmkdirp = promisify(mkdirp); + +const PATH = '.temp'; + +async function reset() { + await primraf(PATH); + await pmkdirp(PATH); +} + +export { + PATH, + reset, +}; diff --git a/test/mocha.opts b/test/mocha.opts index 4a52320..aac536c 100644 --- a/test/mocha.opts +++ b/test/mocha.opts @@ -1 +1,3 @@ +test/src --recursive +--require test/helpers/setup diff --git a/test/src/cli/generate.js b/test/src/cli/generate.js new file mode 100644 index 0000000..ef4e2cb --- /dev/null +++ b/test/src/cli/generate.js @@ -0,0 +1,43 @@ +import generate from '../../../src/cli/generate'; +import firegen from '../../../src'; +import fs from 'fs'; +import path from 'path'; +import { + DEFAULT_ROOT, + CONFIG_FILE, +} from '../../../src/constants'; + +const config = { + config: 'config', +}; +const configFile = path.join( + DEFAULT_ROOT, + CONFIG_FILE, +); + +describe('cli', () => { + describe('generate', () => { + before(async () => { + sinon.stub(firegen, 'generate', () => Promise.resolve()); + sinon.stub(fs, 'readFile', (path, callback) => { + callback(null, JSON.stringify(config)); + }); + await generate(); + }); + after(() => { + firegen.generate.restore(); + fs.readFile.restore(); + }); + + it('should load the config', async () => { + fs.readFile.should.have.been.calledWith(configFile); + }); + + it('should generate the API and rules', async () => { + firegen.generate.should.have.been.calledWith({ + root: DEFAULT_ROOT, + config, + }); + }); + }); +}); diff --git a/test/src/cli/init.js b/test/src/cli/init.js new file mode 100644 index 0000000..200f620 --- /dev/null +++ b/test/src/cli/init.js @@ -0,0 +1,21 @@ +import init from '../../../src/cli/init'; +import firegen from '../../../src'; +import { + DEFAULT_ROOT, +} from '../../../src/constants'; + +describe('cli', () => { + describe('init', () => { + before(async () => { + sinon.stub(firegen, 'init', () => Promise.resolve()); + await init(); + }); + after(() => { + firegen.init.restore(); + }); + + it('should initialise an API project', async () => { + firegen.init.should.have.been.calledWith(DEFAULT_ROOT); + }); + }); +}); diff --git a/test/src/firegen/generate.js b/test/src/firegen/generate.js new file mode 100644 index 0000000..264d8f7 --- /dev/null +++ b/test/src/firegen/generate.js @@ -0,0 +1,74 @@ +import generate from '../../../src/firegen/generate'; +import {stat} from 'fs'; +import promisify from 'es6-promisify'; +import path from 'path'; +import {create} from '../../../src/firegen/init/entry'; +import { + PATH, + reset, +} from '../../helpers/temp-dir'; + +const pstat = promisify(stat); + +const root = path.join( + PATH, + 'project', +); +const entry = 'entry'; +const api = 'api'; +const database = 'database'; +const storage = 'storage'; +const config = { + entry, + output: { + api, + database, + storage, + }, +}; +const entryFile = path.join( + root, + entry, +); +const apiFile = path.join( + root, + api, +); +const databaseFile = path.join( + root, + database, +); +const storageFile = path.join( + root, + storage, +); + +describe('firegen', () => { + describe('generate', () => { + before(async () => { + await reset(); + await create({ + file: entryFile, + }); + await generate({ + root, + config, + }); + }); + + it('should create the api file', async () => { + const stats = await pstat(apiFile); + stats.isFile().should.be.true; + }); + + it('should create the database file', async () => { + const stats = await pstat(databaseFile); + stats.isFile().should.be.true; + }); + + it('should create the storage file', async () => { + const stats = await pstat(storageFile); + stats.isFile().should.be.true; + }); + }); +}); diff --git a/test/src/firegen/index.js b/test/src/firegen/index.js new file mode 100644 index 0000000..b4cd065 --- /dev/null +++ b/test/src/firegen/index.js @@ -0,0 +1,10 @@ +import * as firegen from '../../../src/firegen'; + +describe('firegen', () => { + it('should export init', () => { + firegen.init.should.be.ok; + }); + it('should export generate', () => { + firegen.generate.should.be.ok; + }); +}); diff --git a/test/src/firegen/init/config.js b/test/src/firegen/init/config.js new file mode 100644 index 0000000..64575d3 --- /dev/null +++ b/test/src/firegen/init/config.js @@ -0,0 +1,56 @@ +import {create} from '../../../../src/firegen/init/config'; +import { + readFile, +} from 'fs'; +import promisify from 'es6-promisify'; +import { + PATH, + reset, +} from '../../../helpers/temp-dir'; +import path from 'path'; +import { + CONFIG_FILE, +} from '../../../../src/constants'; + +const preadFile = promisify(readFile); + +const configFile = path.join(PATH, CONFIG_FILE); +const entry = 'entryFile'; +const api = 'apiFile'; +const database = 'databaseFile'; +const storage = 'storageFile'; + +describe('firegen', () => { + describe('init', () => { + describe('config', () => { + describe('create', () => { + before(async () => { + await reset(); + await create({ + root: PATH, + config: { + entry, + output: { + api, + database, + storage, + }, + }, + }); + }); + + it('should create the config file', async () => { + const configJson = await preadFile(configFile); + JSON.parse(configJson).should.eql({ + entry, + output: { + api, + database, + storage, + }, + }); + }); + }); + }); + }); +}); diff --git a/test/src/firegen/init/entry.js b/test/src/firegen/init/entry.js new file mode 100644 index 0000000..23d5eba --- /dev/null +++ b/test/src/firegen/init/entry.js @@ -0,0 +1,37 @@ +import {create} from '../../../../src/firegen/init/entry'; +import loader from '../../../helpers/loader'; +import { + PATH, + reset, +} from '../../../helpers/temp-dir'; +import path from 'path'; + +const entryFile = path.join( + PATH, + 'sub', + 'sub', + 'entry.js', +); + +describe('firegen', () => { + describe('init', () => { + describe('entry', () => { + describe('create', () => { + before(async () => { + await reset(); + await create({ + file: entryFile, + }); + }); + + it('should create the entry file', async () => { + const api = { + add: sinon.spy(), + }; + await loader(entryFile, ['api'], [api]); + api.add.should.have.been.calledWith('my first api'); + }); + }); + }); + }); +}); diff --git a/test/src/firegen/init/index.js b/test/src/firegen/init/index.js new file mode 100644 index 0000000..045cfa6 --- /dev/null +++ b/test/src/firegen/init/index.js @@ -0,0 +1,54 @@ +import init from '../../../../src/firegen/init'; +import * as config from '../../../../src/firegen/init/config'; +import * as entry from '../../../../src/firegen/init/entry'; +import path from 'path'; +import { + PATH, + reset, +} from '../../../helpers/temp-dir'; +import { + DEFAULT_ENTRY, + DEFAULT_API, + DEFAULT_DATABASE, + DEFAULT_STORAGE, +} from '../../../../src/constants'; + +const entryFile = path.join( + PATH, + DEFAULT_ENTRY, +); + +describe('firegen', () => { + describe('init', () => { + before(async () => { + sinon.spy(config, 'create'); + sinon.spy(entry, 'create'); + await reset(); + await init(PATH); + }); + after(() => { + config.create.restore(); + entry.create.restore(); + }); + + it('should create the default config file', () => { + config.create.should.have.been.calledWith({ + root: PATH, + config: { + entry: DEFAULT_ENTRY, + output: { + api: DEFAULT_API, + database: DEFAULT_DATABASE, + storage: DEFAULT_STORAGE, + }, + }, + }); + }); + + it('should create the default entry file', () => { + entry.create.should.have.been.calledWith({ + file: entryFile, + }); + }); + }); +}); diff --git a/test/src/index.js b/test/src/index.js index e7e3d9a..4c8f154 100644 --- a/test/src/index.js +++ b/test/src/index.js @@ -1,10 +1,7 @@ -import test from '../../src/index.js'; -import chai from 'chai'; +import firegen from '../../src'; -chai.should(); - -describe('test', () => { - it('should pass', () => { - test().should.eql('hello world'); +describe('index', () => { + it('should export firegen', () => { + firegen.should.be.ok; }); });