Permalink
Browse files

small adjustments for jsonp

  • Loading branch information...
1 parent 5f70d8b commit 406bfbb5908c8c66b1b001fe8e33e1cddae8fde1 @lancejpollard lancejpollard committed Sep 12, 2012
View
@@ -1,15 +1,17 @@
.DS_Store
.git*
-Cakefile
+Makefile
wiki/
docs/
dist/
examples/
favicon.ico
-Watchfile
+/grunt.coffee
doc/
test/
tmp/
build/
.travis.yml
-ROADMAP.md
+ROADMAP.md
+inspiration.md
+/config.json
View
@@ -24,6 +24,7 @@ You are free to contribute any of these features in any order… I'm more of a f
- *client routes
- testing patterns for an app
- ~~`grunt --config ./grunt.coffee`~~
+- make it more obvious that there is hook.io integration (http://vimeo.com/33288036)
## 0.6.0 - Testing, Robustness
View
@@ -1,2 +1,4 @@
#!/usr/bin/env node
-require('../lib/tower').Command.run(process.argv);
+var path = require('path');
+
+require(path.resolve('../lib/tower')).Command.run(process.argv);
View
@@ -1,9 +1,9 @@
var path = require('path');
require('coffee-script');
-var root = path.join(__dirname, '/lib/tower.js');
+var root = path.join(__dirname, 'lib/tower.js');
if (path.existsSync(root))
module.exports = require(root);
else
- module.exports = require(path.join(__dirname, '/packages/tower.coffee'));
+ module.exports = require(path.join(__dirname, 'packages/tower.coffee'));
@@ -10,12 +10,16 @@ Tower.Controller.addRenderers
# handle and parse your JSON from, such as `function1234567({your: 'data'})`.
# You need JSONP to do `GET` requests across domains (even subdomains).
json: (json, options, callback) ->
+ jsonpCallback = if options.callback != false
+ options.callback || @params.callback
+
unless typeof(json) == 'string'
if @params.pretty && @params.pretty.toString() == 'true'
json = JSON.stringify(json, null, 2)
else
json = JSON.stringify(json)
- json = "#{options.callback}(#{json})" if options.callback
+
+ json = "#{jsonpCallback}(#{json})" if jsonpCallback?
@headers['Content-Type'] ||= require('mime').lookup('json')
callback null, json if callback
json
@@ -95,7 +95,12 @@ Tower.ControllerParams =
cleanConditions(item) for item in value
else
# @todo make more robust
- delete hash[key] unless parsers.hasOwnProperty(key) || key.match(/Id$/)
+ # You should only be able to query the id when
+ # it is:
+ # - included in a route (e.g. nested routes, userId, etc.),
+ # - defined by `belongsTo` on the controller
+ # - defined by `param` on the controller
+ delete hash[key] unless parsers.hasOwnProperty(key) || key.match(/id$/i)
hash
@@ -1,3 +1,28 @@
+# @todo Add method to mocha so you can both pass
+# args to the test description and use those args in the test.
+# @example
+# testWith '/users.json', {user: firstName: 'John'}, (params, done) ->
+# post '/users.json', params, ->
+# assert.equal @body.firstName, 'John'
+#
+# done()
+global.testWith = ->
+ if arguments.length > 2
+ args = _.args(arguments)
+ fn = if typeof args[args.length - 1] == 'function' then args.pop() else null
+ title = _.map(args, (arg) -> JSON.stringify(arg)).join(' ')
+ args.shift() # remote title
+ test title, (done) ->
+ # if it's the same length of the args + 1
+ if fn.length == (args.length + 1)
+ args.push(done)
+ fn.apply(@, args)
+ else
+ fn.apply(@, args)
+ done()
+ else
+ test(arguments...)
+
# https://raw.github.com/plessbd/superagent/f6e7a85555bbd1a70babf62b4d0c0ec674f3d2f5/lib/node/index.js
Tower.start = (port, callback) ->
if typeof port == 'function'
@@ -85,7 +110,7 @@ global.testUpdate = ->
testRequest 'put', arguments...
global.testDestroy = ->
- testRequest 'del', arguments...
+ testRequest 'destroy', arguments...
# @example This is without the helper
# test '/posts.json', (done) ->
@@ -18,7 +18,31 @@ Tower.StoreTransportAjax =
headers: {'X-Requested-With': 'XMLHttpRequest'}
ajax: (params, defaults) ->
- $.ajax($.extend({}, @defaults, defaults, params))
+ $.ajax(@serializeParams(params, defaults))
+
+ serializeParams: (params, defaults) ->
+ params = _.extend({}, @defaults, defaults, params)
+
+ # need to use jsonp if you're using GET cross-domain
+ params = @_adjustParamsForJSONP(params) if params.type == 'GET' && params.dataType == 'json'
+
+ params
+
+ _adjustParamsForJSONP: (params) ->
+ params.dataType = 'jsonp'
+ delete params.contentType
+ # @todo we should come up with a pattern for keeping the url in a URI.js object,
+ # and only turn it into a string in the $.ajax method.
+ # add callback for jquery
+ unless params.url.match(/[\?\&]callback=.+/)
+ callbackParam = 'callback=?'
+ # @todo maybe this simple test should be an underscore helper...
+ separator = if params.url.match('?') then '&' else '?'
+ params.url = "#{params.url}#{separator}#{callbackParam}"
+
+ params.url =
+
+ params
toJSON: (record, method, format) ->
data = {}
@@ -32,6 +56,7 @@ Tower.StoreTransportAjax =
# and that just about seems impossible.
# data._socketId = Tower.connection.id
data.format = format
+
JSON.stringify(data)
disable: (callback) ->
@@ -191,12 +216,8 @@ Tower.StoreTransportAjax =
# {users: [user1, user1...], conditions: {}, page: 2, limit: 20, sort: []}
# and all we need to do is load it back into the cursor
(data, status, xhr) =>
- try
- #callback(null, cursor.build(data))
- data = cursor.model.load(data)
- callback(null, data) if callback
- catch error
- callback(error) if callback
+ data = cursor.model.load(data)
+ callback(null, data) if callback
findFailure: (cursor, callback) ->
@failure(cursor, callback)
@@ -200,4 +200,18 @@ class Tower.Store extends Tower.Class
else
@find(cursor, callback)
+ # This is called by {Tower.Cursor#find} or {Tower.Store#find}.
+ #
+ # If you pass a hash to {Tower.Store#find} it will convert it to a cursor;
+ # once it has a cursor it then passes it to this method. This is purely an optimization.
+ #
+ # @todo
+ findWithCursor: ->
+
+ createWithCursor: ->
+
+ updateWithCursor: ->
+
+ destroyWithCursor: ->
+
module.exports = Tower.Store
@@ -170,10 +170,12 @@ _.extend Tower,
if Tower.autoNotifyCursors
Ember.run.schedule('sync', @, @notifyCursors)
- notifyCursors: ->
+ notifyCursors: (force) ->
cursors = {}
- for path of Tower.cursorsToUpdate
+ paths = _.keys(if force then Tower.cursors else Tower.cursorsToUpdate)
+
+ for path of paths
cursor = Tower.getCursor(path)
# this just makes it so we don't run the same one twice
cursors[Ember.guidFor(cursor)] = cursor if cursor
@@ -65,5 +65,65 @@ describe 'Tower.ControllerParams', ->
assert.equal 1, posts.length
done()
+ describe 'JSON API', ->
+ post = null
+ firstPostId = null
+ lastPostId = null
+
+ beforeEach (done) ->
+ App.Post.all (error, records) =>
+ post = records[0]
+ firstPostId = post.get('id').toString()
+ lastPostId = records[1].get('id').toString()
+
+ done()
+
+ describe 'id', ->
+ test '=', (done) ->
+ params = conditions: id: firstPostId
+
+ _.get '/posts', params: params, (response) ->
+ posts = response.controller.get('posts')
+ assert.equal 1, posts.length
+ assert.equal firstPostId, posts[0].get('id').toString()
+ done()
+
+ test '$eq', (done) ->
+ params = conditions: id: $eq: firstPostId
+
+ _.get '/posts', params: params, (response) ->
+ posts = response.controller.get('posts')
+ assert.equal 1, posts.length
+ assert.equal firstPostId, posts[0].get('id').toString()
+ done()
+
+ # @todo doesn't work in mongodb
+ #test '$neq', (done) ->
+ # params = conditions: id: $neq: firstPostId
+ #
+ # _.get '/posts', params: params, (response) ->
+ # posts = response.controller.get('posts')
+ # assert.equal 1, posts.length
+ # assert.equal lastPostId, posts[0].get('id').toString()
+ # done()
+
+ test '$in', (done) ->
+ params = conditions: id: $in: [firstPostId]
+
+ _.get '/posts', params: params, (response) ->
+ posts = response.controller.get('posts')
+ assert.equal 1, posts.length
+ assert.equal firstPostId, posts[0].get('id').toString()
+ done()
+
+ test '$nin', (done) ->
+ params = conditions: id: $nin: [firstPostId]
+
+ _.get '/posts', params: params, (response) ->
+ posts = response.controller.get('posts')
+ assert.equal 1, posts.length
+ assert.equal lastPostId, posts[0].get('id').toString()
+ done()
+
test 'date string is serialized to database'
# params = user: birthdate: _(26).years().ago().toDate()
@@ -0,0 +1,2 @@
+describe 'Tower.Model fetch', ->
+

0 comments on commit 406bfbb

Please sign in to comment.