Browse files

Mature version.

  • Loading branch information...
1 parent 2ae796b commit 1a5451bea481ba26916602e79b2be5940062931f @vesln committed Jan 28, 2012
Showing with 289 additions and 14 deletions.
  1. +1 −0 .gitignore
  2. +9 −0 Makefile
  3. 0 bin/box
  4. +28 −0 lib/app.js
  5. +50 −1 lib/cli.js
  6. +89 −1 lib/commands.js
  7. +20 −9 lib/storage.js
  8. +2 −1 package.json
  9. +24 −0 test/app.test.js
  10. +39 −1 test/cli.test.js
  11. +27 −1 test/commands.test.js
View
1 .gitignore
@@ -1,4 +1,5 @@
node_modules/
+data/config.json
*._
*.tmp
.monitor
View
9 Makefile
@@ -0,0 +1,9 @@
+TESTS = test/*.test.js
+
+test:
+ @NODE_ENV=test ./node_modules/.bin/mocha \
+ --require should \
+ --reporter spec \
+ $(TESTS)
+
+.PHONY: test
View
0 bin/box 100644 → 100755
File mode changed.
View
28 lib/app.js
@@ -0,0 +1,28 @@
+/*!
+ * Box - Powerful key -> value storage for the CLI.
+ *
+ * Veselin Todorov <hi@vesln.com>
+ * MIT License.
+ */
+
+/**
+ * Module dependencies.
+ */
+var flatiron = require('flatiron');
+
+/**
+ * The application object.
+ *
+ * @type {Object}
+ */
+var app = module.exports = flatiron.app;
+
+// Usage.
+app.use(flatiron.plugins.cli, {
+ usage: [
+ '',
+ 'box',
+ '',
+ 'Usage:'
+ ]
+});
View
51 lib/cli.js
@@ -3,4 +3,53 @@
*
* Veselin Todorov <hi@vesln.com>
* MIT License.
- */
+ */
+
+/**
+ * Module dependencies.
+ */
+var path = require('path');
+
+/**
+ * The application object.
+ *
+ * @type {Object}
+ */
+var app = module.exports = require('./app');
+
+/**
+ * Commands.
+ *
+ * @type {Object}
+ */
+var commands = require('./commands');
+
+/**
+ * Storage.
+ *
+ * @type {Object}
+ */
+var storage = require('./storage');
+
+// Initializes the storage.
+storage.load(
+ path.join(__dirname, '..', 'data', 'config.json'),
+ function(err) {
+ if (err) throw err;
+ }
+);
+
+// Lists all records.
+app.cmd(/ls/, commands.list);
+
+// Removes a record.
+app.cmd(/rm ([^\s]+)/, commands.delete);
+
+// Version.
+app.cmd(/version/, commands.version);
+
+// Returns a record's value.
+app.cmd(/([^\s]+$)/, commands.get);
+
+// Sets new record.
+app.cmd(/([^\s]+) (.+)/, commands.set);
View
90 lib/commands.js
@@ -3,4 +3,92 @@
*
* Veselin Todorov <hi@vesln.com>
* MIT License.
- */
+ */
+
+/**
+ * Commands namespace.
+ *
+ * @type {Object}
+ */
+var commands = module.exports;
+
+/**
+ * Print alias.
+ */
+var print = console.log;
+
+/**
+ * The application.
+ *
+ * @type {Object}
+ */
+var app = require('./app');
+
+/**
+ * Storage. Just an alias to application config.
+ *
+ * @type {Object}
+ */
+var storage = require('./storage');
+
+/**
+ * Prints current version.
+ *
+ * @api public
+ */
+commands.version = function() {
+ print(require('../package.json').version);
+};
+
+/**
+ * Deletes a record.
+ *
+ * @param {String} Key.
+ * @api public
+ */
+commands.delete = function(key) {
+ storage.del(key, function() {
+ storage.save(function(err) {
+ if (err) throw err;
+ });
+ });
+};
+
+/**
+ * Prints a value.
+ *
+ * @param {String} Key.
+ * @api public
+ */
+commands.get = function(key) {
+ storage.get(key, function(val) {
+ print(val || 'Nothing found.');
+ });
+};
+
+/**
+ * Saves a record.
+ *
+ * @param {String} Key.
+ * @api public
+ */
+commands.set = function(key, value) {
+ storage.set(key, value, function() {
+ storage.save(function(err) {
+ if (err) throw err;
+ });
+ });
+};
+
+/**
+ * Lists all records.
+ *
+ * @api public
+ */
+commands.list = function() {
+ storage.get(function(data) {
+ Object.keys(data).forEach(function(key) {
+ print(key + ': ' + data[key]);
+ });
+ });
+};
View
29 lib/storage.js
@@ -19,6 +19,13 @@ var path = require('path');
var storage = module.exports;
/**
+ * Data container.
+ *
+ * @type {Object}
+ */
+storage.data = {};
+
+/**
* Sets a value.
*
* @param {String} Key.
@@ -70,15 +77,19 @@ storage.save = function(cb) {
* @param {Function} Callback.
* @api public
*/
-storage.load = function(file, cb) {
- var self = this;
- this.source = file;
- fs.readFile(file, 'utf8', function(err, data) {
- if (err && err.code !== 'ENOENT') return cb(err);
- self.data = data || {};
- cb(null);
- });
-};
+ storage.load = function(file, cb) {
+ this.source = file;
+ this.data = {};
+
+ try {
+ var content = fs.readFileSync(file, 'utf8');
+ this.data = JSON.parse(content);
+ } catch(err) {
+ if (err && err.code !== 'ENOENT') return cb(err);
+ }
+
+ cb(null);
+ };
/**
* Destroies a storage.
View
3 package.json
@@ -10,6 +10,7 @@
, "devDependencies": {
"mocha": "0.3.3"
, "should": "0.3.2"
+ , "sinon": "1.3.1"
}
, "repository" : {
"type" : "git"
@@ -19,7 +20,7 @@
, "scripts": {
"test": "make test"
}
- , "main": "./lib/index"
+ , "main": "./lib/cli"
, "engines": {
"node": ">= 0.6.0 < 0.7.0"
}
View
24 test/app.test.js
@@ -0,0 +1,24 @@
+/*!
+ * Box - Powerful key -> value storage for the CLI.
+ *
+ * Veselin Todorov <hi@vesln.com>
+ * MIT License.
+ */
+
+/**
+ * Test dependencies.
+ */
+var flatiron = require('flatiron');
+
+/**
+ * The tests object.
+ *
+ * @type {Object}
+ */
+var app = require('../lib/app');
+
+describe('app', function() {
+ it('should be flatiron app', function() {
+ app.should.eql(flatiron.app);
+ });
+});
View
40 test/cli.test.js
@@ -3,4 +3,42 @@
*
* Veselin Todorov <hi@vesln.com>
* MIT License.
- */
+ */
+
+/**
+ * Test dependencies.
+ */
+var flatiron = require('flatiron');
+var path = require('path');
+
+/**
+ * The tests object.
+ *
+ * @type {Object}
+ */
+var cli = require('../lib/cli');
+
+/**
+ * Support.
+ */
+var storage = require('../lib/storage');
+var commands = require('../lib/commands');
+
+describe('cli', function() {
+ it('should expose flatiron app', function() {
+ cli.should.eql(flatiron.app);
+ });
+
+ it('should configure the storage', function() {
+ storage.source.should.eql(path.join(__dirname, '..', 'data', 'config.json'));
+ });
+
+ it('should register routes', function() {
+ cli.router.routes.ls.on.should.eql(commands.list);
+ cli.router.routes.version.on.should.eql(commands.version);
+ cli.router.routes.rm['([^\\s]+)'].on.should.eql(commands.delete);
+ cli.router.routes.rm['([^\\s]+)'].on.should.eql(commands.delete);
+ cli.router.routes['([^\\s]+$)'].on.should.eql(commands.get);
+ cli.router.routes['([^\\s]+)']['(.+)'].on.should.eql(commands.set);
+ });
+});
View
28 test/commands.test.js
@@ -3,4 +3,30 @@
*
* Veselin Todorov <hi@vesln.com>
* MIT License.
- */
+ */
+
+/**
+ * Support.
+ */
+var storage = require('../storage');
+
+/**
+ * The tests object.
+ *
+ * @type {Object}
+ */
+var commands = require('../lib/commands');
+
+describe('commands', function() {
+ describe('.version()', function() {
+ it('should be sane', function() {
+ commands.version.should.be.ok
+ });
+ });
+
+ describe('.delete()', function() {
+ it('should call storage.delete and storage.save', function() {
+
+ });
+ });
+});

0 comments on commit 1a5451b

Please sign in to comment.