Permalink
Browse files

Initial commit

  • Loading branch information...
0 parents commit 0f109042fdc17c14459037d4a55948b20073b33a @dgf committed Mar 12, 2012
Showing with 496 additions and 0 deletions.
  1. +2 −0 .gitignore
  2. +31 −0 Cakefile
  3. +22 −0 LICENSE
  4. +3 −0 README.md
  5. +89 −0 lib/crudl.js
  6. +38 −0 package.json
  7. +18 −0 spec/Term.coffee
  8. +32 −0 spec/concurrent.spec.coffee
  9. +166 −0 spec/crudl.spec.coffee
  10. +17 −0 spec/helper/check.coffee
  11. +13 −0 spec/helper/db.coffee
  12. +65 −0 src/crudl.coffee
@@ -0,0 +1,2 @@
+.idea/
+node_modules
@@ -0,0 +1,31 @@
+fs = require 'fs'
+{print} = require 'util'
+{spawn, exec} = require 'child_process'
+jasmineBinary = './node_modules/jasmine-node/bin/jasmine-node'
+
+# ANSI Terminal Colors
+bold = '\033[0;1m'
+green = '\033[0;32m'
+reset = '\033[0m'
+red = '\033[0;31m'
+
+log = (message, color) -> console.log color + message + reset
+
+call = (name, options, callback) ->
+ proc = spawn name, options
+ proc.stdout.on 'data', (data) -> print data.toString()
+ proc.stderr.on 'data', (data) -> log data.toString(), red
+ proc.on 'exit', callback
+
+build = (callback) -> call 'coffee', ['-c', '-o', 'lib', 'src'], callback
+
+spec = (callback) -> call jasmineBinary, ['spec', '--coffee'], callback
+
+task 'build', 'build coffee', ->
+ build (status) -> log ":)", green if status is 0
+
+task 'spec', 'run specifications', ->
+ build (buildStatus) ->
+ if buildStatus is 0
+ spec (testStatus) ->
+ log ":)", green if testStatus is 0
22 LICENSE
@@ -0,0 +1,22 @@
+
+Copyright (c) 2012 Danny Gräf
+
+see http://www.opensource.org/licenses/MIT
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,3 @@
+CRUDL Sequelize Wrapper
+
+supports handy helpers to create, update, persist, find and list instances smoothly with coffee
@@ -0,0 +1,89 @@
+(function() {
+ var findAll, findAndExecute, validateAndSave, _,
+ __hasProp = Object.prototype.hasOwnProperty;
+
+ _ = require('underscore');
+
+ validateAndSave = function(instance, onSuccess, onError) {
+ var errors;
+ errors = instance.validate();
+ if (errors) {
+ return onError('validation failed', errors);
+ } else {
+ return instance.save().success(onSuccess).error(onError);
+ }
+ };
+
+ findAndExecute = function(model, options, onError, onSuccess) {
+ return model.find(options).error(onError).success(onSuccess);
+ };
+
+ findAll = function(model, options, onSuccess, onError) {
+ return model.all(options).error(onError).success(function(instances) {
+ return onSuccess(_.toArray(instances));
+ });
+ };
+
+ module.exports = function(model) {
+ var interface, method, name, _ref;
+ interface = {};
+ _ref = model.options.classMethods;
+ for (name in _ref) {
+ if (!__hasProp.call(_ref, name)) continue;
+ method = _ref[name];
+ interface[name] = method;
+ }
+ interface.create = function(values, onSuccess, onError) {
+ var instance;
+ instance = model.build(values);
+ return validateAndSave(instance, onSuccess, onError);
+ };
+ interface.update = function(options, values, onSuccess, onError) {
+ return findAndExecute(model, options, onError, function(instance) {
+ var prop, value;
+ for (prop in values) {
+ if (!__hasProp.call(values, prop)) continue;
+ value = values[prop];
+ instance[prop] = value;
+ }
+ return validateAndSave(instance, onSuccess, onError);
+ });
+ };
+ interface["delete"] = function(options, onSuccess, onError) {
+ return findAndExecute(model, options, onError, function(instance) {
+ return instance.destroy().error(onError).success(onSuccess);
+ });
+ };
+ interface.find = function(options, onSuccess, onError) {
+ return findAndExecute(model, options, onError, onSuccess);
+ };
+ interface.all = function(onSuccess, onError) {
+ return findAll(model, null, onSuccess, onError);
+ };
+ interface.list = function(options, onSuccess, onError) {
+ return findAll(model, options, onSuccess, onError);
+ };
+ interface.persist = function(options, values, onSuccess, onError) {
+ return findAndExecute(model, options, onError, function(instance) {
+ var prop, value;
+ if (instance != null) {
+ for (prop in values) {
+ if (!__hasProp.call(values, prop)) continue;
+ value = values[prop];
+ instance[prop] = value;
+ }
+ } else {
+ instance = model.build(values);
+ }
+ return validateAndSave(instance, onSuccess, onError);
+ });
+ };
+ interface.reset = function(onSuccess, onError) {
+ return model.sync({
+ force: true
+ }).success(onSuccess).error(onError);
+ };
+ return interface;
+ };
+
+}).call(this);
@@ -0,0 +1,38 @@
+{
+ "name": "crudl-model"
+ , "version": "0.0.1"
+ , "author": "Danny Gräf <github@dagnu.de>"
+
+ , "keywords": ["Sequelize", "ORM", "CRUD", "coffeescript"]
+ , "description": "coffeescript friendly Sequelize CRUD delegate (API improvement)"
+ , "homepage": "http://github.com/dgf/crudl-model"
+ , "main": "lib/crudl.js"
+
+ , "licenses": [{
+ "type": "MIT"
+ , "url": "http://github.com/dgf/crudl-model/raw/master/LICENSE"
+ }]
+ , "repository": {
+ "type": "git"
+ , "url": "git@github.com:dgf/crudl-model.git"
+ }
+
+ , "dependencies": {
+ "coffee-script": "1.2.x"
+ , "underscore": "1.3.x"
+ , "sequelize": "1.3.x"
+ }
+ , "devDependencies": {
+ "jasmine-node": "1.0.x"
+ , "sqlite3": "2.1.x"
+ }
+
+ , "engine": {
+ "node": "0.6.x"
+ }
+ , "scripts": {
+ "pretest": "cake build"
+ , "prepublish": "cake build"
+ , "test": "cake spec"
+ }
+}
@@ -0,0 +1,18 @@
+Sequelize = require 'sequelize'
+
+module.exports = (sequelize) ->
+
+ Term = sequelize.define 'Term',
+
+ title:
+ type: Sequelize.STRING
+ allowNull: false
+ unique: true
+ validate:
+ notEmpty: true
+
+ definition:
+ type: Sequelize.TEXT
+ allowNull: false
+ validate:
+ notEmpty: true
@@ -0,0 +1,32 @@
+Sequelize = require 'sequelize'
+path = require 'path'
+crudl = require '../src/crudl'
+check = require './helper/check'
+db = require './helper/db'
+
+Term = require('./Term') db.createSqliteMemoryDb()
+
+# attention: stateful test spec, beware of right order
+xdescribe 'concurrent data access', ->
+# system under test
+ SUT = null
+ term =
+ title: 'title'
+ definition: 'description'
+
+ it 'needs a synchronisable model', ->
+ SUT = crudl Term
+ test = (success, fail) ->
+ SUT.reset success, fail
+ assert = (actual) -> expect(actual).toBeTruthy 'sync state'
+ check 'crudl term and sync model', test, assert
+
+ it 'creates a new term', ->
+ # create real estate
+ test = (success, fail) -> SUT.create term, success, fail
+
+ assert = (actual) ->
+ expect(actual.id).toBeDefined 'term id'
+ expect(actual.title).toBe term.title, 'term title'
+
+ check 'create new term', test, assert
Oops, something went wrong.

0 comments on commit 0f10904

Please sign in to comment.