diff --git a/README.md b/README.md
index 20b0f0d..683a4d3 100644
--- a/README.md
+++ b/README.md
@@ -54,6 +54,7 @@ meteor
* [create](#create)
* [make:collection](#makecollection)
* [make:command](#makecommand)
+* [make:container](#makecontainer)
* [make:migration](#makemigration)
* [make:seeder](#makeseeder)
* [make:view](#makeview)
@@ -113,6 +114,23 @@ lib
You can then call your command using `dispatch(CommandName, arg1, arg2)` or `dispatchAsync(CommandName, arg1, arg2, callback);`.
+## make:container
+
+```sh
+kitty make:container [Namespace] ViewName
+```
+
+This command will create a React container for the
+given ViewName:
+
+```
+client
+└──containers
+ └──[Namespace]
+ └── ViewName
+ └── ViewNameContainer.jsx
+```
+
## make:meteor-method
```sh
diff --git a/scaffolding/project/.meteor/packages b/scaffolding/project/.meteor/packages
index f897047..0438b7e 100644
--- a/scaffolding/project/.meteor/packages
+++ b/scaffolding/project/.meteor/packages
@@ -19,20 +19,20 @@ ecmascript # Enable ECMAScript2015+ syntax in app code
autopublish # Publish all data to the clients (for prototyping)
insecure # Allow all DB writes from clients (for prototyping)
-jsx
-react
-react-runtime
-react-meteor-data
-kadira:flow-router
-kadira:react-layout
+react # React, includes jsx and react-runtime
+react-meteor-data # Mixin for React components
+kadira:flow-router # Non-reactive router
+kadira:react-layout # Layouts for React routes
-fourseven:scss
-poetic:materialize-scss
-fortawesome:fontawesome
+fourseven:scss # SCSS support
+poetic:materialize-scss # Materialize with SCSS files
+fortawesome:fontawesome # FontAwesome
-tap:i18n
+tap:i18n # Internationalization support
-aldeed:collection2
+aldeed:collection2 # Schemas for Mongo collections
+
+sanjo:jasmine # Jasmine Tests
capsulecat:react-bem
capsulecat:commands
diff --git a/scaffolding/templates/container.jsx.handlebars b/scaffolding/templates/container.jsx.handlebars
new file mode 100644
index 0000000..6660261
--- /dev/null
+++ b/scaffolding/templates/container.jsx.handlebars
@@ -0,0 +1,27 @@
+/**
+ * {{#if hasNamespace}}{{namespace}} {{/if}}{{name}}
+ */
+{{#if hasNamespace}}
+{{namespace}} = typeof {{namespace}} === 'undefined' ? {} : {{namespace}};
+
+{{namespace}}.{{/if}}{{name}}Container = React.createClass({
+ mixins: [ReactMeteorData, ReactBEM],
+ getMeteorData() {
+ return {};
+ },
+ getInitialState() {
+ return {};
+ },
+ componentDidMount() {
+ //
+ },
+ bem_blocks: ['{{nameDashed}}'],
+ {{#if hasNamespace}}
+ bem_block_modifiers: ['{{namespaceDashed}}'],
+ {{/if}}
+ bem_render() {
+ return (
+ <{{#if hasNamespace}}{{namespace}}.{{/if}}{{name}} />
+ );
+ }
+});
diff --git a/scaffolding/templates/test-spec.js.handlebars b/scaffolding/templates/test-spec.js.handlebars
new file mode 100644
index 0000000..2d13667
--- /dev/null
+++ b/scaffolding/templates/test-spec.js.handlebars
@@ -0,0 +1,5 @@
+describe('{{name}}', function () {
+ it('is true', function () {
+ expect(true).toBe(false);
+ });
+});
diff --git a/scaffolding/templates/view.jsx.handlebars b/scaffolding/templates/view.jsx.handlebars
index 876b047..045a33a 100644
--- a/scaffolding/templates/view.jsx.handlebars
+++ b/scaffolding/templates/view.jsx.handlebars
@@ -5,19 +5,11 @@
{{namespace}} = typeof {{namespace}} === 'undefined' ? {} : {{namespace}};
{{namespace}}.{{/if}}{{name}} = React.createClass({
- mixins: [ReactMeteorData, ReactBEM],
- getMeteorData() {
- return {};
- },
- getInitialState() {
- return {};
- },
+ mixins: [React.addons.PureRenderMixin, ReactBEM],
+ propTypes: {},
getDefaultProps() {
return {};
},
- componentDidMount() {
- //
- },
bem_blocks: ['{{nameDashed}}'],
{{#if hasNamespace}}
bem_block_modifiers: ['{{namespaceDashed}}'],
@@ -25,7 +17,7 @@
bem_render() {
return (
-
Hello
+
{{#if hasNamespace}}{{namespace}} {{/if}}{{name}} says Hello
);
}
diff --git a/src/commands/MakeContainerCommand.js b/src/commands/MakeContainerCommand.js
new file mode 100644
index 0000000..420969d
--- /dev/null
+++ b/src/commands/MakeContainerCommand.js
@@ -0,0 +1,60 @@
+var Handlebars = require('handlebars');
+var read = require('read-file');
+var write = require('write');
+var path = require('path');
+var fs = require('fs');
+var MakeUtilities = require('../utilities/MakeUtilities');
+
+var MakeContainerCommand = function () {
+ var _arguments = Array.prototype.slice.call(arguments);
+ var _namespace = (_arguments.length > 1 ? _arguments[0] : '');
+ var _namespaceDashed = MakeUtilities.camelToDash(_namespace);
+ var _hasNamespace = (_arguments.length > 1);
+ var _name = (_arguments.length > 1 ? _arguments[1] : _arguments[0] );
+ var _nameDashed = MakeUtilities.camelToDash(_name);
+
+ var _templatePath = function() {
+ return path.join(__dirname, '..', '..', 'scaffolding', 'templates', 'container.jsx.handlebars');
+ }
+
+ var _createPath = function(workingDirectory) {
+ // TODO allow the user to create the new view from anywhere in the project (not just the root)
+ var componentRoot = path.join(workingDirectory, 'client', 'containers');
+
+ if (_hasNamespace) {
+ componentRoot = path.join(componentRoot, _namespace);
+ }
+
+ componentRoot = path.join(componentRoot, _name);
+
+ return componentRoot;
+ }
+
+ var _templatize = function (templatePath) {
+ var raw = read.sync(templatePath, { encoding: 'utf8' });
+ var template = Handlebars.compile(raw);
+ return template({
+ namespace: _namespace,
+ namespaceDashed: _namespaceDashed,
+ hasNamespace: _hasNamespace,
+ name: _name,
+ nameDashed: _nameDashed
+ });
+ }
+
+ var handle = function () {
+ var jsxContent = _templatize(_templatePath());
+
+ var workingDirectory = process.cwd();
+ var base = _createPath(workingDirectory);
+
+ write.sync(path.join(base, _name + 'Container.jsx'), jsxContent);
+
+ };
+
+ return {
+ handle: handle
+ }
+};
+
+module.exports = MakeContainerCommand;
diff --git a/src/commands/MakeTestCommand.js b/src/commands/MakeTestCommand.js
new file mode 100644
index 0000000..68df777
--- /dev/null
+++ b/src/commands/MakeTestCommand.js
@@ -0,0 +1,68 @@
+var Handlebars = require('handlebars');
+var read = require('read-file');
+var write = require('write');
+var path = require('path');
+var fs = require('fs');
+var MakeUtilities = require('../utilities/MakeUtilities');
+
+var MakeTestCommand = function () {
+ var _arguments = Array.prototype.slice.call(arguments);
+ var _name = (_arguments.length > 1 ? _arguments[1] : _arguments[0] );
+ var _nameDashed = MakeUtilities.camelToDash(_name);
+
+ var _testRunner = 'jasmine';
+ var _typeOfTest = 'integration';
+
+ var _templatePath = function() {
+ return path.join(__dirname, '..', '..', 'scaffolding', 'templates', 'test-spec.js.handlebars');
+ }
+
+ var _createPath = function(workingDirectory) {
+ // TODO allow the user to create the new view from anywhere in the project (not just the root)
+ var componentRoot = path.join(workingDirectory, 'test', _testRunner);
+
+ if (_typeOfTest === 'integration') {
+ componentRoot = path.join(componentRoot, 'client');
+ } else if (_typeOfTest === 'unit' ) {
+ componentRoot = path.join(componentRoot, 'server');
+ }
+
+ componentRoot = path.join(componentRoot, _typeOfTest);
+
+ return componentRoot;
+ }
+
+ var _templatize = function (templatePath) {
+ var raw = read.sync(templatePath, { encoding: 'utf8' });
+ var template = Handlebars.compile(raw);
+ return template({
+ name: _name,
+ nameDashed: _nameDashed
+ });
+ }
+
+ var handle = function (flags) {
+ _typeOfTest = (function () {
+ if (flags.indexOf('--integration') !== -1) {
+ return 'integration';
+ } else if (flags.indexOf('--unit') !== -1) {
+ return 'unit';
+ } else {
+ return 'integration';
+ }
+ })();
+
+ var jsContent = _templatize(_templatePath());
+
+ var workingDirectory = process.cwd();
+ var base = _createPath(workingDirectory);
+
+ write.sync(path.join(base, _name + '-spec.js'), jsContent);
+ };
+
+ return {
+ handle: handle
+ }
+};
+
+module.exports = MakeTestCommand;
diff --git a/src/commands/PrintDocumentationCommand.js b/src/commands/PrintDocumentationCommand.js
index 67fc8f7..93020d2 100644
--- a/src/commands/PrintDocumentationCommand.js
+++ b/src/commands/PrintDocumentationCommand.js
@@ -8,8 +8,9 @@ var PrintDocumentationCommand = function () {
console.log('├── db');
console.log('| └── seed ─ Seed the database using your seeders');
console.log('├── make');
- console.log('| ├── command ─ Create a dispatchable command');
console.log('| ├── collection ─ Create a collection (only supports Mongo)');
+ console.log('| ├── command ─ Create a dispatchable command');
+ console.log('| ├── container ─ Create a React container for a View');
console.log('| ├── meteor-method ─ Create a Meteor method');
console.log('| ├── model-factory ─ Create a model factory for the given collection');
console.log('| ├── migration ─ Create a migration (uses percolate:migrations)');
diff --git a/src/strategies/CommandStrategy.js b/src/strategies/CommandStrategy.js
index e52e19d..84c60cf 100644
--- a/src/strategies/CommandStrategy.js
+++ b/src/strategies/CommandStrategy.js
@@ -1,6 +1,7 @@
var MeowCommand = require('../commands/MeowCommand');
var CreateCommand = require('../commands/CreateCommand');
var MakeViewCommand = require('../commands/MakeViewCommand');
+var MakeContainerCommand = require('../commands/MakeContainerCommand');
var MakeCommandCommand = require('../commands/MakeCommandCommand');
var MakeCollectionCommand = require('../commands/MakeCollectionCommand');
var MakeMeteorMethodCommand = require('../commands/MakeMeteorMethodCommand');
@@ -14,6 +15,7 @@ var MakeModelFactoryCommand = require('../commands/MakeModelFactoryCommand');
var MakeSeederCommand = require('../commands/MakeSeederCommand');
var AddSeederRunnerCommand = require('../commands/AddSeederRunnerCommand');
var SeedDatabaseCommand = require('../commands/SeedDatabaseCommand');
+var MakeTestCommand = require('../commands/MakeTestCommand');
var CommandStrategy = function(commandPattern, args, flags) {
var _commander = function(klass) {
@@ -49,6 +51,8 @@ var CommandStrategy = function(commandPattern, args, flags) {
case 'make:collection':
_commander(MakeCollectionCommand);
break;
+ case 'make:container':
+ _commander(MakeContainerCommand);
case 'make:migration':
_commander(AddMigrationPackageCommand);
_commander(MakeMigrationCommand);
@@ -61,6 +65,9 @@ var CommandStrategy = function(commandPattern, args, flags) {
_commander(MakeSeederCommand);
_commander(AddSeederRunnerCommand);
break;
+ case 'make:test':
+ _commander(MakeTestCommand);
+ break;
case 'remind-me:react-loop':
_reminder(ReactLoopReminder);
break;