Permalink
Browse files

Add generator+documentation functions

  • Loading branch information...
1 parent 7391dfa commit 7f700e8c0f3bfde70acbf0627b5928849a2130d7 @timoxley timoxley committed Dec 22, 2011
Showing with 121 additions and 40 deletions.
  1. +16 −10 lib/kin.js
  2. +42 −16 tests/examples/kin-examples.js
  3. +63 −14 tests/kin_test.js
View
@@ -68,7 +68,7 @@ function generate(type, overrideProperties, callback) {
)
})
}
-Kin.prototype._getGeneratorFunction = function(type) {
+Kin.prototype._getGeneratorFunction = function(type, fixedOverrideProperties) {
var self = this
var generatorFunction = function(overrideProperties, callback) {
if (arguments.length == 1 && typeof overrideProperties == 'function') {
@@ -89,42 +89,48 @@ Kin.prototype._getGeneratorFunction = function(type) {
}
})
}
+
var returnFunction = function(overrideProperties, callback) {
if (arguments.length == 1 && typeof overrideProperties == 'function') {
callback = overrideProperties
overrideProperties = {}
}
+ overrideProperties = _.extend(returnFunction._overrideProperties, overrideProperties)
generatorFunction(overrideProperties, function(err, model, meta) {
var functionList = _.clone(returnFunction._postFunctions)
functionList.unshift(function(next) {
next(err, model, meta)
})
async.waterfall(functionList, function(err, model, meta) {
+ returnFunction.items.push(model)
callback.call(model, err, model, meta)
})
})
}
+
returnFunction._postFunctions = []
+ returnFunction._overrideProperties = fixedOverrideProperties || {}
returnFunction.post = function(func) {
returnFunction._postFunctions.push(func)
}
+ returnFunction.items = []
return returnFunction
}
Kin.prototype.generate = function(type, overrideProperties, callback) {
// TODO Clean this mess up.
var self = this
// properties is optional
- if (arguments.length >= 2) {
- if (arguments.length == 2 && typeof overrideProperties == 'function') {
- callback = overrideProperties
- overrideProperties = {}
- }
- if (!type) {
- if (callback) return callback(new Error('No Type'))
- }
+ if (arguments.length == 2 && typeof overrideProperties == 'function') {
+ callback = overrideProperties
+ overrideProperties = {}
+ }
+ if (!type) {
+ return callback(new Error('No Type'))
+ }
+ if (callback) {
return this._getGeneratorFunction(type)(overrideProperties, callback)
- } else if (arguments.length == 1) {
+ } else {
return this._getGeneratorFunction(type, overrideProperties)
}
}
@@ -328,27 +328,21 @@ kin.generate('UserG', {_streams: 0}, function(err, user, meta) {
})
})
-// Example: if you also want to save nested items, you could do
-// this in the 'top level' generator's post function (e.g. save documents via
-// documents stored in the meta parameter in User's post function)
+// Example: `save` all generated Users and Streams
kin.post('UserG', function(user, meta, callback) {
- user.save(function(saveErr, user) {
- var numSavedStreams = 0
- for(var i = 0; i < meta.streams.length; i++) {
- var stream = meta.streams[i]
- var streamSaveErrs
- stream.save(function(streamSaveErr) {
- streamSaveErrs = streamSaveErr
- numSavedStreams++
- if (numSavedStreams == meta.streams.length) {
- callback(saveErr || streamSaveErrs, user, meta)
- }
- })
- }
+ user.save(function(err, user) {
+ callback(err, user, meta)
+ })
+})
+
+kin.post('Stream', function(stream, meta, callback) {
+ stream.save(function(err, stream) {
+ callback(err, stream, meta)
})
})
+
kin.generate('UserG', {_streams: 3}, function(err, user, meta) {
User.findById(user._id, function(err, found) {
assert.ok(found) // ensure user was saved
@@ -360,3 +354,35 @@ kin.generate('UserG', {_streams: 3}, function(err, user, meta) {
+// ## Generator functions
+// Generator functions can be created so you can apply specific changes
+// to a generator, in a certain situation. To create a generator function
+// simply call `generate` with no callback. You can use generator functions
+// just like normal, or use their additional properties to make modifications.
+
+
+/* Simple example */
+var generateUser = kin.generate('UserA')
+
+generateUser(function(err, user, meta) {
+ assert.deepEqual(user, {username: 'joe', email: 'joe@example.com'}) // as normal
+})
+
+// Pass override properties when creating the generator function or when
+// generating objects
+
+/*
+ * All Users generated with this function will by default have username: bill,
+ * overriding the value `joe` provided in the blueprint.
+ */
+var generateUser = kin.generate('UserA', {username: 'bill'})
+
+generateUser(function(err, user, meta) {
+ assert.deepEqual(user, {username: 'bill', email: 'joe@example.com'}) // as normal
+})
+
+generateUser({email: 'bill@example.com'}, function(err, user, meta) {
+ assert.deepEqual(user, {username: 'bill', email: 'bill@example.com'}) // as normal
+})
+
+
View
@@ -779,30 +779,57 @@ var tests = testCase({
}
}),
'generator function': {
- 'called with one argument, generates a generator function': function(test) {
+ 'called with no callback, generates a generator function': function(test) {
kin.blueprint('User', {
username: 'joe'
})
var userGenerator = kin.generate('User')
- test.equal('function', typeof userGenerator)
+ test.equal(typeof userGenerator, 'function')
userGenerator(function(err, user) {
if (err) throw err
test.ok(user)
test.equal(user.username, 'joe')
test.done()
})
},
- 'can be passed overridden properties': function(test) {
- kin.blueprint('User', {
- username: 'joe'
- })
- var userGenerator = kin.generate('User')
- userGenerator({username: 'bob'}, function(err, user) {
- if (err) throw err
- test.ok(user)
- test.equal(user.username, 'bob')
- test.done()
- })
+ 'can be passed overridden properties': {
+ 'when creating generator function': function(test) {
+ kin.blueprint('User', {
+ username: 'joe'
+ })
+ var userGenerator = kin.generate('User', {username: 'bob'})
+ userGenerator(function(err, user) {
+ if (err) throw err
+ test.ok(user)
+ test.equal(user.username, 'bob')
+ test.done()
+ })
+ },
+ 'at generate time' : function(test) {
+ kin.blueprint('User', {
+ username: 'joe'
+ })
+ var userGenerator = kin.generate('User')
+ userGenerator({username: 'bob'}, function(err, user) {
+ if (err) throw err
+ test.ok(user)
+ test.equal(user.username, 'bob')
+ test.done()
+ })
+ },
+ 'at both function creation and object generation time': function(test) {
+ kin.blueprint('User', {
+ username: 'joe',
+ email: 'joe@example.com'
+ })
+ var userGenerator = kin.generate('User', {username: 'bob'})
+ userGenerator({email: 'bob@example.com'}, function(err, user) {
+ if (err) throw err
+ test.ok(user)
+ test.equal(user.username, 'bob')
+ test.done()
+ })
+ }
},
'generator function can have post functions given to it': function(test) {
kin.blueprint('User', {
@@ -844,7 +871,29 @@ var tests = testCase({
test.equal(user.email, 'gary@example.com')
test.done()
})
- }
+ },
+ 'keeps a cache of all generated items': function(test) {
+ kin.blueprint('User', {
+ username: 'joe'
+ })
+ var userGenerator = kin.generate('User')
+ userGenerator(function(err, user) {
+ if (err) throw err
+ userGenerator({username: 'bob'}, function(err, user) {
+ if (err) throw err
+ test.ok(user)
+ test.equal(user.username, 'bob')
+ test.equal(userGenerator.items.length, 2)
+ test.ok(_.find(userGenerator.items, function(user) {
+ return user.username == 'bob'
+ }))
+ test.ok(_.find(userGenerator.items, function(user) {
+ return user.username == 'joe'
+ }))
+ test.done()
+ })
+ })
+ },
}
},

0 comments on commit 7f700e8

Please sign in to comment.