diff --git a/test/archive/README.md b/test/archive/README.md new file mode 100644 index 0000000000..27eaee4c77 --- /dev/null +++ b/test/archive/README.md @@ -0,0 +1,3 @@ +These are tests which are no longer used. While we could delete them and depend on git history for later lookup, +I think it's important these are visible to developers since they may have valuable tests which haven't been ported +to our new setup. Once a file is ported or determined useless, feel free to delete. \ No newline at end of file diff --git a/test/archive/api.mocha.coffee b/test/archive/api.mocha.coffee new file mode 100644 index 0000000000..cf9d276f03 --- /dev/null +++ b/test/archive/api.mocha.coffee @@ -0,0 +1,656 @@ +_ = require 'lodash' +expect = require 'expect.js' +require 'coffee-script' +async = require 'async' +superagentDefaults = require 'superagent-defaults' + +request = superagentDefaults() + +conf = require("nconf") +conf.argv().env().file({file: __dirname + '../config.json'}).defaults +conf.set('port','1337') + +# Override normal ENV values with nconf ENV values (ENV values are used the same way without nconf) +#FIXME can't get nconf file above to load... +process.env.BASE_URL = conf.get("BASE_URL") +process.env.FACEBOOK_KEY = conf.get("FACEBOOK_KEY") +process.env.FACEBOOK_SECRET = conf.get("FACEBOOK_SECRET") +process.env.NODE_DB_URI = 'mongodb://localhost/habitrpg' + +User = require('../../src/models/user').model +Group = require('../../src/models/group').model +Challenge = require('../../src/models/challenge').model + +app = require '../../src/server' + +## monkey-patch expect.js for better diffs on mocha +## see: https://github.com/LearnBoost/expect.js/pull/34 +#origBe = expect.Assertion::be +#expect.Assertion::be = expect.Assertion::equal = (obj) -> +# @_expected = obj +# origBe.call this, obj + +# Custom modules +shared = require 'habitrpg-shared' + +###### Helpers & Variables ###### + +model = null +uuid = null +taskPath = null +baseURL = 'http://localhost:3000/api/v2' + +### + expect().eql expects object keys to be in the correct order, this sorts that out +### + +expectUserEqual = (u1, u2) -> + [u1, u2] = _.map [u1, u2], (obj) -> + 'update__ stats.toNextLevel stats.maxHealth __v'.split(' ').forEach (path) -> + helpers.dotSet path, null, obj + sorted = {} + _.each _.keys(obj).sort(), (k) -> sorted[k] = obj[k] + sorted.tasks = _.sortBy sorted.tasks, 'id' + sorted +# console.log {u1, u2} + expect(u1).to.eql(u2) + +expectSameValues = (obj1, obj2, paths) -> + _.each paths, (k) -> + expect(helpers.dotGet(k,obj1)).to.eql helpers.dotGet(k,obj2) + +expectCode = (res, code) -> + expect(res.body.err).to.be undefined if code is 200 + expect(res.statusCode).to.be code + +###### Specs ###### + +describe 'API', -> + user = null + _id = null + apiToken = null + username = null + password = null + + registerNewUser = (cb, main=true)-> + randomID = shared.uuid() + [username,password] = [randomID,randomID] if main + request.post("#{baseURL}/register") + .set('Accept', 'application/json') + .send({ + username: randomID + password: randomID + confirmPassword: randomID + email: "#{randomID}@gmail.com" + }) + .end (res) -> + return cb(null,res.body) unless main + {_id,apiToken} = res.body + console.log {_id,apiToken} + User.findOne {_id, apiToken}, (err, _user) -> + expect(err).to.not.be.ok + user = _user + request + .set('Accept', 'application/json') + .set('X-API-User', _id) + .set('X-API-Key', apiToken) + cb null, res.body + + before (done)-> + require '../../src/server' #start the server + # then wait for it to do it's thing. TODO make a cb-compatible export of server + setTimeout done, 2000 + + describe 'Without token or user id', -> + it '/api/v2/status', (done) -> + request.get("#{baseURL}/status") + .set('Accept', 'application/json') + .end (res) -> + expect(res.statusCode).to.be 200 + expect(res.body.status).to.be 'up' + done() + + it '/api/v2/user', (done) -> + request.get("#{baseURL}/user") + .set('Accept', 'application/json') + .end (res) -> + expect(res.statusCode).to.be 401 + expect(res.body.err).to.be 'You must include a token and uid (user id) in your request' + done() + + describe 'With token and user id', -> + currentUser = null + + before (done) -> + registerNewUser(done,true) + + beforeEach (done) -> + User.findById _id, (err,_user) -> + currentUser = _user + done() + + ############ + # Groups + ############ + + describe 'Groups', -> + group = undefined + + before (done) -> + request.post("#{baseURL}/groups") + .send({name:"TestGroup", type:"party"}) + .end (res) -> + expectCode res, 200 + group = res.body + expect(group.members.length).to.be 1 + expect(group.leader).to.be user._id + done() + + describe 'Challenges', -> + challenge = undefined + updateTodo = undefined + + it 'Creates a challenge', (done) -> + request.post("#{baseURL}/challenges") + .send({ + group:group._id + dailys: [{type:'daily',text:'Challenge Daily'}] + todos: [{type:'todo', text:'Challenge Todo', notes:'Challenge Notes'}] + rewards: [] + habits: [] + official: true + }) + .end (res) -> + expectCode res, 200 + async.parallel [ + (cb) -> User.findById _id, cb + (cb) -> Challenge.findById res.body._id, cb + ], (err, results) -> + [_user,challenge] = [results[0],results[1]] + expect(_user.dailys[_user.dailys.length-1].text).to.be('Challenge Daily') + updateTodo = _user.todos[_user.todos.length-1] + expect(updateTodo.text).to.be('Challenge Todo') + expect(challenge.official).to.be false + done() + + it 'User updates challenge notes', (done) -> + updateTodo.notes = "User overriden notes" + request.put("#{baseURL}/user/tasks/#{updateTodo.id}") + .send(updateTodo) + .end (res) -> + done() #we'll do the check down below + + it 'Change challenge daily', (done) -> + challenge.dailys[0].text = 'Updated Daily' + challenge.todos[0].notes = 'Challenge Updated Todo Notes' + request.post("#{baseURL}/challenges/#{challenge._id}") + .send(challenge) + .end (res) -> + setTimeout -> + User.findById _id, (err,_user) -> + expectCode res, 200 + expect(_user.dailys[_user.dailys.length-1].text).to.be('Updated Daily') + expect(res.body.todos[0].notes).to.be('Challenge Updated Todo Notes') + expect(_user.todos[_user.todos.length-1].notes).to.be('User overriden notes') + currentUser = _user + done() + , 500 # we have to wait a while for users' tasks to be updated, called async on server + + it 'Shows user notes on challenge page', (done) -> + request.get("#{baseURL}/challenges/#{challenge._id}/member/#{_id}") + .end (res) -> + expect(res.body.todos[res.body.todos.length-1].notes).to.be('User overriden notes') + done() + + it 'Complete To-Dos', (done) -> + u = currentUser + request.post("#{baseURL}/user/tasks/#{u.todos[0].id}/up").end (res) -> + request.post("#{baseURL}/user/tasks/#{u.todos[1].id}/up").end (res) -> + request.post("#{baseURL}/user/tasks/").send({type:'todo'}).end (res) -> + request.post("#{baseURL}/user/tasks/clear-completed").end (res) -> + expect(_.size res.body).to.be 2 + done() + + it 'Admin creates a challenge', (done) -> + User.findByIdAndUpdate _id, {$set:{'contributor.admin':true}}, (err,_user) -> + expect(err).to.not.be.ok + + async.parallel [ + (cb)-> + request.post("#{baseURL}/challenges") + .send({group:group._id, dailys: [], todos: [], rewards: [], habits: [], official: false}).end (res) -> + expect(res.body.official).to.be false + cb() + (cb)-> + request.post("#{baseURL}/challenges") + .send({group:group._id, dailys: [], todos: [], rewards: [], habits: [], official: true}).end (res) -> + expect(res.body.official).to.be true + cb() + ], done + + + describe 'Quests', -> + party = undefined + participating = [] + notParticipating = [] + + it 'Invites some members', (done) -> + async.waterfall [ + + # Register new users + (cb) -> + async.parallel [ + (cb2) -> registerNewUser(cb2,false) + (cb2) -> registerNewUser(cb2,false) + (cb2) -> registerNewUser(cb2,false) + ], cb + + # Send them invitations + (_party, cb) -> + party = _party + async.parallel [ + (cb2) -> request.post("#{baseURL}/groups/#{group._id}/invite?uuid=#{party[0]._id}").end (-> cb2()) + (cb2) -> request.post("#{baseURL}/groups/#{group._id}/invite?uuid=#{party[1]._id}").end (-> cb2()) + (cb2) -> request.post("#{baseURL}/groups/#{group._id}/invite?uuid=#{party[2]._id}").end (-> cb2()) + ], cb + + # Accept / Reject + (results, cb) -> + #series since they'll be modifying the same group record + async.series (_.reduce party, (m,v,i) -> + m.push (cb2) -> + request.post("#{baseURL}/groups/#{group._id}/join") + .set('X-API-User', party[i]._id) + .set('X-API-Key', party[i].apiToken) + .end (res) -> cb2() + m + , []), cb + + # Make sure the invites stuck + (whatever, cb) -> + Group.findById group._id, (err, g) -> + expect(g.members.length).to.be 4 + cb() + + ], (err, results) -> + expect(err).to.be.ok + done() + + it 'Starts a quest', (done) -> + async.waterfall [ + (cb)-> + request.post("#{baseURL}/groups/#{group._id}/questAccept?key=evilsanta") + .end (res) -> + expectCode(res, 401) + User.findByIdAndUpdate _id, {$set:'items.quests.evilsanta':1}, cb + (_user,cb)-> + request.post("#{baseURL}/groups/#{group._id}/questAccept?key=evilsanta") + .end (res) -> + expectCode(res, 200) + Group.findById group._id,cb + (_group,cb)-> + group = _group #refresh local group + expect(group.quest.key).to.be 'evilsanta' + + async.series (_.reduce party, (m,v,i) -> + m.push (cb2) -> + request.post("#{baseURL}/groups/#{group._id}/questAccept") + .set('X-API-User', party[i]._id) + .set('X-API-Key', party[i].apiToken) + .end (res) -> cb2() + m + , []), cb + + ], done + + it "Doesn't include people who aren't participating" + + +# ############ +# # Batch Update +# ############ +# +# describe 'Batch Update', -> +# +# it 'POST /api/v1/batch-update', (done) -> +# userBefore = _.cloneDeep(currentUser) +# +# ops = [ +# # Good scores +# op: 'score', params: {id:user.habits[0].id, direction: 'up'} +# op: 'score', params: {id:user.habits[1].id, direction: 'down'} +# op: 'score', params: {id:user.dailys[0].id, direction: 'up'} +# op: 'score', params: {id:user.todos[0].id, direction: 'up'} +# ] +# +# request.post("#{baseURL}/user/batch-update") +# .send(ops) +# .end (res) -> +# expect(res.body.err).to.be undefined +# expect(res.statusCode).to.be 200 +# #expectUserEqual(userBefore, res.body) +# done() +# +# +# ############ +# # To Be Updated (these are old v1 tests which haven't been touched in over 6 months, need to be portd to new API tests or deleted) +# ############ +# +# it.skip 'POST /api/v2/batch-update (handles corrupt values)', (done) -> +# registerNewUser (_res) -> +# # corrupt the tasks, and let's see how the server handles this +# ids = _res.dailyIds +# _res.tasks[ids[0]].value = NaN +# _res.tasks[ids[1]].value = undefined +# _res.tasks[ids[2]] = {} +# _res.tasks["undefined"] = {} +# +# _res.stats.hp = _res.stats.gp = NaN +# +# _res.lastCron = +new Date('08/13/2013') +# +# ops = [ +# op: 'score', task: _res.tasks[ids[0]], dir: 'up' +# ] +# +# model.set "users.#{_res.id}", _res, -> +# request.post("#{baseURL}/user/batch-update") +# .set('Accept', 'application/json') +# .set('X-API-User', _res.id) +# .set('X-API-Key', _res.apiToken) +# .send(ops) +# .end (res) -> +# expect(res.statusCode).to.be 200 +# console.log {stats:res.body.stats, tasks:res.body.tasks} +# done() +# +# +# #FIXME figure out how to compare the objects +# it.skip 'GET /api/v1/user', (done) -> +# request.get("#{baseURL}/user") +# .end (res) -> +# expect(res.body.err).to.be undefined +# expect(res.statusCode).to.be 200 +# expect(res.body.id).not.to.be.empty() +# self = _.clone(currentUser) +# delete self.apiToken +# self.stats.toNextLevel = 150 +# self.stats.maxHealth = 50 +# +# expectUserEqual(res.body, self) +# done() +# +# it.skip 'GET /api/v1/user/task/:id', (done) -> +# tid = _.pluck(currentUser.tasks, 'id')[0] +# request.get("#{baseURL}/user/task/#{tid}") +# .end (res) -> +# expect(res.body.err).to.be undefined +# expect(res.statusCode).to.be 200 +# expect(res.body).to.eql currentUser.tasks[tid] +# done() +# +# it.skip 'POST /api/v1/user/task', (done) -> +# request.post("#{baseURL}/user/task") +# .send({title: 'Title', text: 'Text', type: 'habit'}) +# .end (res) -> +# query = model.query('users').withIdAndToken(currentUser.id, currentUser.apiToken) +# query.fetch (err, user) -> +# expect(res.body.err).to.be undefined +# expect(res.statusCode).to.be 201 +# expect(res.body.id).not.to.be.empty() +# # Ensure that user owns the newly created object +# saved = user.get("tasks.#{res.body.id}") +# expect(saved).to.be.an('object') +# done() +# +# it.skip 'POST /api/v1/user/task (without type)', (done) -> +# request.post("#{baseURL}/user/task") +# .send({}) +# .end (res) -> +# expect(res.body.err).to.be 'type must be habit, todo, daily, or reward' +# expect(res.statusCode).to.be 400 +# done() +# +# it.skip 'POST /api/v1/user/task (only type)', (done) -> +# request.post("#{baseURL}/user/task") +# .send(type: 'habit') +# .end (res) -> +# query = model.query('users').withIdAndToken(currentUser.id, currentUser.apiToken) +# query.fetch (err, user) -> +# expect(res.body.err).to.be undefined +# expect(res.statusCode).to.be 201 +# expect(res.body.id).not.to.be.empty() +# # Ensure that user owns the newly created object +# expect(user.get().tasks[res.body.id]).to.be.an('object') +# # Ensure that value gets set to 0 since not otherwise specified +# expect(user.get().tasks[res.body.id].value).to.be.equal(0) +# done() +# +# it.skip 'PUT /api/v1/user/task/:id', (done) -> +# tid = _.pluck(currentUser.tasks, 'id')[0] +# request.put("#{baseURL}/user/task/#{tid}") +# .send(text: 'bye') +# .end (res) -> +# expect(res.body.err).to.be undefined +# expect(res.statusCode).to.be 200 +# currentUser.tasks[tid].text = 'bye' +# expectSameValues res.body, currentUser.tasks[tid], ['id','type','text'] +# #expect(res.body).to.eql currentUser.tasks[tid] +# done() +# +# it.skip 'PUT /api/v1/user/task/:id (shouldnt update type)', (done) -> +# tid = _.pluck(currentUser.tasks, 'id')[1] +# type = if currentUser.tasks[tid].type is 'habit' then 'daily' else 'habit' +# request.put("#{baseURL}/user/task/#{tid}") +# .send(type: type, text: 'fishman') +# .end (res) -> +# expect(res.body.err).to.be undefined +# expect(res.statusCode).to.be 200 +# currentUser.tasks[tid].text = 'fishman' +# expect(res.body).to.eql currentUser.tasks[tid] +# done() +# +# it.skip 'PUT /api/v1/user/task/:id (update notes)', (done) -> +# tid = _.pluck(currentUser.tasks, 'id')[2] +# request.put("#{baseURL}/user/task/#{tid}") +# .send(text: 'hi',notes:'foobar matey') +# .end (res) -> +# expect(res.body.err).to.be undefined +# expect(res.statusCode).to.be 200 +# currentUser.tasks[tid].text = 'hi' +# currentUser.tasks[tid].notes = 'foobar matey' +# expect(res.body).to.eql currentUser.tasks[tid] +# done() +# +# it.skip 'GET /api/v1/user/tasks', (done) -> +# request.get("#{baseURL}/user/tasks") +# .end (res) -> +# query = model.query('users').withIdAndToken(currentUser.id, currentUser.apiToken) +# query.fetch (err, user) -> +# expect(res.body.err).to.be undefined +# expect(user.get()).to.be.ok() +# expect(res.statusCode).to.be 200 +# model.ref '_user', user +# tasks = [] +# for type in ['habit','todo','daily','reward'] +# model.refList "_#{type}List", "_user.tasks", "_user.#{type}Ids" +# tasks = tasks.concat model.get("_#{type}List") +# # Ensure that user owns the tasks +# expect(res.body.length).to.equal tasks.length +# # Ensure that the two sets are equal +# expect(_.difference(_.pluck(res.body,'id'), _.pluck(tasks,'id')).length).to.equal 0 +# done() +# +# it.skip 'GET /api/v1/user/tasks (todos)', (done) -> +# request.get("#{baseURL}/user/tasks") +# .query(type:'todo') +# .end (res) -> +# query = model.query('users').withIdAndToken(currentUser.id, currentUser.apiToken) +# query.fetch (err, user) -> +# expect(res.body.err).to.be undefined +# expect(res.statusCode).to.be 200 +# model.ref '_user', user +# model.refList "_todoList", "_user.tasks", "_user.todoIds" +# tasks = model.get("_todoList") +# # Ensure that user owns the tasks +# expect(res.body.length).to.equal tasks.length +# # Ensure that the two sets are equal +# expect(_.difference(_.pluck(res.body,'id'), _.pluck(tasks,'id')).length).to.equal 0 +# done() +# +# it.skip 'DELETE /api/v1/user/task/:id', (done) -> +# tid = currentUser.habitIds[2] +# request.del("#{baseURL}/user/task/#{tid}") +# .end (res) -> +# expect(res.body.err).to.be undefined +# expect(res.statusCode).to.be 204 +# query = model.query('users').withIdAndToken(currentUser.id, currentUser.apiToken) +# query.fetch (err, user) -> +# expect(user.get('habitIds').indexOf(tid)).to.be -1 +# expect(user.get("tasks.#{tid}")).to.be undefined +# done() +# +# it.skip 'DELETE /api/v1/user/task/:id (no task found)', (done) -> +# tid = "adsfasdfjunkshouldntbeatask" +# request.del("#{baseURL}/user/task/#{tid}") +# .end (res) -> +# expect(res.statusCode).to.be 400 +# expect(res.body.err).to.be 'No task found.' +# done() +# +# it.skip 'POST /api/v1/user/task/:id/up (habit)', (done) -> +# tid = currentUser.habitIds[0] +# request.post("#{baseURL}/user/task/#{tid}/up") +# .send({}) +# .end (res) -> +# expect(res.body.err).to.be undefined +# expect(res.statusCode).to.be 200 +# expect(res.body).to.eql { gp: 1, exp: 7.5, lvl: 1, hp: 50, delta: 1 } +# done() +# +# it.skip 'POST /api/v1/user/task/:id/up (daily)', (done) -> +# tid = currentUser.dailyIds[0] +# request.post("#{baseURL}/user/task/#{tid}/up") +# .send({}) +# .end (res) -> +# expect(res.body.err).to.be undefined +# expect(res.statusCode).to.be 200 +# expect(res.body).to.eql { gp: 2, exp: 15, lvl: 1, hp: 50, delta: 1 } +# query = model.query('users').withIdAndToken(currentUser.id, currentUser.apiToken) +# query.fetch (err, user) -> +# expect(user.get("tasks.#{tid}.completed")).to.be true +# done() +# +# it.skip 'POST /api/v1/user/task (array)', (done) -> +# habitId = currentUser.habitIds[0] +# dailyId = currentUser.dailyIds[0] +# arr = [{ +# id: habitId +# text: 'hello' +# notes: 'note' +# },{ +# text: 'new task' +# notes: 'notes!' +# },{ +# id: dailyId +# del: true +# }] +# +# request.post("#{baseURL}/user/tasks") +# .send(arr) +# .end (res) -> +# expect(res.body.err).to.be undefined +# expect(res.statusCode).to.be 201 +# +# expectSameValues res.body[0], {id: habitId,text: 'hello',notes: 'note'}, ['id','text','notes'] +# expect(res.body[1].id).to.be.a 'string' +# expect(res.body[1].text).to.be 'new task' +# expect(res.body[1].notes).to.be 'notes!' +# expect(res.body[2]).to.eql deleted: true +# +# query = model.query('users').withIdAndToken(currentUser.id, currentUser.apiToken) +# query.fetch (err, user) -> +# expectSameValues user.get("tasks.#{habitId}"), {id: habitId,text: 'hello',notes: 'note'}, ['id','text','notes'] +# expect(user.get("tasks.#{dailyId}")).to.be undefined +# expectSameValues user.get("tasks.#{res.body[1].id}"), {id: res.body[1].id, text: 'new task', notes: 'notes!'}, ['id','text','notes'] +# done() +# +# it.skip 'PUT /api/v1/user (bad path)', (done) -> +# # These updates should not save, as per the API changes +# userUpdates = +# stats: hp: 30 +# flags: itemsEnabled: true +# tasks: [{ +# text: 'hello2' +# notes: 'note2' +# }] +# +# request.put("#{baseURL}/user") +# .send(userUpdates) +# .end (res) -> +# expect(res.body.err).to.be.ok() +# expect(res.statusCode).to.be 500 +# done() +# +# it.skip 'PUT /api/v1/user', (done) -> +# userBefore = {} +# query = model.query('users').withIdAndToken(currentUser.id, currentUser.apiToken) +# query.fetch (err, user) -> +# userBefore = user.get() +# +# habitId = currentUser.habitIds[0] +# dailyId = currentUser.dailyIds[0] +# updates = {} +# updates['stats.hp'] = 30 +# updates['flags.itemsEnabled'] = true +# updates["tasks.#{habitId}.text"] = 'hello2' +# updates["tasks.#{habitId}.notes"] = 'note2' +# +# request.put("#{baseURL}/user") +# .send(updates) +# .end (res) -> +# expect(res.body.err).to.be undefined +# expect(res.statusCode).to.be 200 +# changesWereMade = (obj) -> +# expect(obj.stats.hp).to.be 30 +# expect(obj.flags.itemsEnabled).to.be true +# expectSameValues _.find(obj.tasks,{id:habitId}), {id: habitId,text: 'hello2',notes: 'note2'}, ['id','text','notes'] +# changesWereMade res.body +# query.fetch (err, user) -> +# changesWereMade user.get() +# done() +# +# it.skip 'POST /api/v1/user/auth/local', (done) -> +# userAuth = {username, password} +# request.post("#{baseURL}/user/auth/local") +# .set('Accept', 'application/json') +# .send(userAuth) +# .end (res) -> +# expect(res.body.err).to.be undefined +# expect(res.statusCode).to.be 200 +# expect(res.body.id).to.be currentUser.id +# expect(res.body.token).to.be currentUser.apiToken +# done() +# +# it.skip 'POST /api/v1/user/auth/facebook', (done) -> +# id = shared.uuid() +# userAuth = facebook_id: 12345, name: 'Tyler Renelle', email: 'x@y.com' +# newUser = helpers.newUser(true) +# newUser.id = id +# newUser.auth = facebook: +# id: userAuth.facebook_id +# name: userAuth.name +# email: userAuth.email +# model.set "users.#{id}", newUser, -> +# +# request.post("#{baseURL}/user/auth/facebook") +# .set('Accept', 'application/json') +# .send(userAuth) +# .end (res) -> +# expect(res.body.err).to.be undefined +# expect(res.statusCode).to.be 200 +# expect(res.body.id).to.be newUser.id +# #expect(res.body.token).to.be newUser.apiToken +# done() +# +# diff --git a/test/casper/dailies.casper.coffee b/test/archive/casper/dailies.casper.coffee similarity index 100% rename from test/casper/dailies.casper.coffee rename to test/archive/casper/dailies.casper.coffee diff --git a/test/casper/general.casper.coffee b/test/archive/casper/general.casper.coffee similarity index 100% rename from test/casper/general.casper.coffee rename to test/archive/casper/general.casper.coffee diff --git a/test/casper/habits.casper.coffee b/test/archive/casper/habits.casper.coffee similarity index 100% rename from test/casper/habits.casper.coffee rename to test/archive/casper/habits.casper.coffee diff --git a/test/casper/helpers.coffee b/test/archive/casper/helpers.coffee similarity index 100% rename from test/casper/helpers.coffee rename to test/archive/casper/helpers.coffee diff --git a/test/casper/items.casper.coffee b/test/archive/casper/items.casper.coffee similarity index 100% rename from test/casper/items.casper.coffee rename to test/archive/casper/items.casper.coffee diff --git a/test/casper/memoryleak.casper.coffee b/test/archive/casper/memoryleak.casper.coffee similarity index 100% rename from test/casper/memoryleak.casper.coffee rename to test/archive/casper/memoryleak.casper.coffee diff --git a/test/casper/registration.casper.coffee b/test/archive/casper/registration.casper.coffee similarity index 100% rename from test/casper/registration.casper.coffee rename to test/archive/casper/registration.casper.coffee diff --git a/test/casper/rest.casper.coffee b/test/archive/casper/rest.casper.coffee similarity index 100% rename from test/casper/rest.casper.coffee rename to test/archive/casper/rest.casper.coffee diff --git a/test/casper/todos.casper.coffee b/test/archive/casper/todos.casper.coffee similarity index 100% rename from test/casper/todos.casper.coffee rename to test/archive/casper/todos.casper.coffee diff --git a/test/test2/casper/add.items.coffee b/test/archive/test2/casper/add.items.coffee similarity index 100% rename from test/test2/casper/add.items.coffee rename to test/archive/test2/casper/add.items.coffee diff --git a/test/test2/casper/stats.coffee b/test/archive/test2/casper/stats.coffee similarity index 100% rename from test/test2/casper/stats.coffee rename to test/archive/test2/casper/stats.coffee diff --git a/test/test2/readme.md b/test/archive/test2/readme.md similarity index 100% rename from test/test2/readme.md rename to test/archive/test2/readme.md diff --git a/test/includes/lodash.min.js b/test/includes/lodash.min.js deleted file mode 100644 index 40126c4a5d..0000000000 --- a/test/includes/lodash.min.js +++ /dev/null @@ -1,42 +0,0 @@ -/*! - Lo-Dash 1.0.0-rc.3 lodash.com/license - Underscore.js 1.4.3 underscorejs.org/LICENSE -*/ -;(function(e,t){function n(e){if(e&&typeof e=="object"&&e.__wrapped__)return e;if(!(this instanceof n))return new n(e);this.__wrapped__=e}function r(e,t,n){t||(t=0);var r=e.length,i=r-t>=(n||tt);if(i)for(var s={},n=t-1;++nt||typeof e=="undefined")return 1;if( -ei;i++)r+="i='"+e.j[i]+"';if(","constructor"==e.j[i]&&(r+="!(f&&f.prototype===l)&&"),r+="h.call(l,i)){"+e.g+"}"}if(e.b||e.h)r+="}";return r+=e.c+";return t" -,n("e,h,j,k,p,n,s","return function("+t+"){"+r+"}")(u,Et,v,N,nn,At,xt)}function f(e){return"\\"+rn[e]}function l(e){return hn[e]}function c(e){return typeof e.toString!="function"&&typeof (e+"")=="string"}function h(){}function p(e,t,n){t||(t=0),typeof n=="undefined"&&(n=e?e.length:0);for(var r=-1,n=n-t||0,i=Array(0>n?0:n);++rn?Ot(0,i+n):n)||0;return typeof i=="number"?s=-1<(N(e)?e.indexOf(t,n):R(e,t,n)):an(e,function(e){if(++r>=n)return!(s=e===t)}),s} -function A(e,t,n){var r=!0,t=u(t,n);if(vn(e))for(var n=-1,i=e.length;++nr&&(r=n,a=e)});else for(;++sa&&(a=e[s]);return a}function H(e,t){return D(e,t+"")}function B(e,t,n,r){var i=3>arguments.length,t=u(t,r,et);if(vn(e)){var s=-1,o= -e.length;for(i&&(n=e[++s]);++sarguments.length;if(typeof s!="number")var a=gn(e),s=a.length;else Gt&&N(e)&&(i=e.split(""));return t=u(t,r,et),_(e,function(e,r,u){r=a?a[--s]:--s,n=o?(o=!1,i[r]):t(n,i[r],r,u)}),n}function F(e,t,n){var r,t=u(t,n);if(vn(e))for(var n=-1,i=e.length;++nn?Ot(0,i+n):n||0)-1;else if(n)return r=z(e,t),e[r]===t?r:-1;for(;++r>>1,n(e[r])R(a,c))(n||f)&&a.push(c),o.push(r)}return o}function X(e,t){return zt||Nt&&2|{(\/]|\[\D|\b(?:delete|in|instanceof|new|typeof|void)\b/,it=/&(?:amp|lt|gt|quot|#x27);/g,st=/\b__p\+='';/g,ot=/\b(__p\+=)''\+/g,ut=/(__e\(.*?\)|\b__t\))\+'';/g,at=/\w*$/,ft=/(?:__e|__t=)\(\s*(?![\d\s"']|this\.)/g -,lt=RegExp("^"+(Y.valueOf+"").replace(/[.*+?^=!:${}()|[\]\/\\]/g,"\\$&").replace(/valueOf|for [^\]]+/g,".+?")+"$"),ct=/\$\{((?:(?=\\?)\\?[\s\S])*?)}/g,ht=/<%=([\s\S]+?)%>/g,pt=/($^)/,dt=/[&<>"']/g,vt=/['\n\r\t\u2028\u2029\\]/g,mt="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" "),gt=Math.ceil,yt=G.concat,bt=Math.floor,wt=lt.test(wt=Object.getPrototypeOf)&&wt,Et=Y.hasOwnProperty,St=G.push,xt=Y.propertyIsEnumerable,Tt=Y.toString,Nt=lt.test(Nt= -p.bind)&&Nt,Ct=lt.test(Ct=Array.isArray)&&Ct,kt=e.isFinite,Lt=e.isNaN,At=lt.test(At=Object.keys)&&At,Ot=Math.max,Mt=Math.min,_t=Math.random,Dt="[object Arguments]",Pt="[object Array]",Ht="[object Boolean]",Bt="[object Date]",jt="[object Number]",Ft="[object Object]",It="[object RegExp]",qt="[object String]",Rt=!!e.attachEvent,Ut=Nt&&!/\n|true/.test(Nt+Rt),zt=Nt&&!Ut,Wt=At&&(Rt||Ut),Xt,Vt,$t=($t={0:1,length:1},G.splice.call($t,0,1),$t[0]),Jt=!0;(function(){function e(){this.x=1}var t=[];e.prototype= -{valueOf:1,y:1};for(var n in new e)t.push(n);for(n in arguments)Jt=!n;Xt=!/valueOf/.test(t),Vt="x"!=t[0]})(1);var Kt=arguments.constructor==Object,Qt=!v(arguments),Gt="xx"!="x"[0]+Object("x")[0];try{var Yt=("[object Object]",Tt.call(document)==Ft)}catch(Zt){}var en={"[object Function]":!1};en[Dt]=en[Pt]=en[Ht]=en[Bt]=en[jt]=en[Ft]=en[It]=en[qt]=!0;var tn={};tn[Pt]=Array,tn[Ht]=Boolean,tn[Bt]=Date,tn[Ft]=Object,tn[jt]=Number,tn[It]=RegExp,tn[qt]=String;var nn={"boolean":!1,"function":!0,object:!0, -number:!1,string:!1,"undefined":!1},rn={"\\":"\\","'":"'","\n":"n","\r":"r"," ":"t","\u2028":"u2028","\u2029":"u2029"};n.templateSettings={escape:/<%-([\s\S]+?)%>/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:ht,variable:""};var sn={a:"o,v,g",k:"for(var a=1,b=typeof g=='number'?2:arguments.length;a":">",'"':""","'":"'"},pn=w(hn),dn=a(sn,{g:"if(t[i]==null)"+sn.g}),vn=Ct||function(e){return Kt&&e instanceof Array||Tt.call(e)==Pt};S(/x/)&&(S=function(e){return e instanceof Function||"[object Function]"==Tt.call(e)});var mn=wt?function(e){if(!e||typeof e!="object")return!1;var t=e.valueOf,n=typeof t=="function"&&(n=wt(t))&&wt(n);return n?e==n||wt(e)==n&&!v(e):m(e) -}:m,gn=At?function(e){return typeof e=="function"&&xt.call(e,"prototype")?g(e):x(e)?At(e):[]}:g;n.after=function(e,t){return 1>e?t():function(){if(1>--e)return t.apply(this,arguments)}},n.assign=fn,n.bind=X,n.bindAll=function(e){for(var t=arguments,n=1R(f,l)){u&&f.push(l);for(var h=n;--h;)if(!(i[h]||(i[h]=r(t[h],0,100)))(l))continue e;a.push(l)}}return a},n.invert=w,n.invoke=function(e,t){var n=p(arguments,2),r=typeof t=="function",i=[];return _(e,function(e){i.push((r?t:e[t]).apply(e,n))}),i},n.keys=gn,n.map=D, -n.max=P,n.memoize=function(e,t){var n={};return function(){var r=t?t.apply(this,arguments):arguments[0];return Et.call(n,r)?n[r]:n[r]=e.apply(this,arguments)}},n.merge=C,n.min=function(e,t,n){var r=Infinity,s=-1,o=e?e.length:0,a=r;if(t||!vn(e))t=!t&&N(e)?i:u(t,n),an(e,function(e,n,i){n=t(e,n,i),nR(s,n,1))i[n]=e}),i},n.once=function(e){var t,n=!1;return function(){return n?t:(n=!0,t=e.apply(this,arguments),e=null,t)}},n.pairs=function(e){var t=[];return cn(e,function(e,n){t.push([n,e])}),t},n.partial=function(e){return o(e,p(arguments,1))},n.pick=function(e,t,n){var r={};if(typeof t!="function")for(var i=0,s=yt.apply(G,arguments),o=s.length;++i=f?(clearTimeout(o),o=null,u=a,i=e.apply(s,r)):o||(o=setTimeout(n,f)),i}},n.times=function(e,t,n){for(var e=+e||0,r=-1,i=Array(e);++rn?Ot(0,r+n):Mt(n,r-1))+1);r--;)if(e[r]===t)return r;return-1},n.mixin=$,n.noConflict=function(){return e._=nt,this},n.random=function(e,t){return null==e&&null==t&&(t=1),e=+e||0,null==t&&(t=e,e=0),e+bt(_t()*((+t||0)-e+1))},n.reduce=B,n.reduceRight=j,n.result=function(e,t){var n=e?e[t]:null;return S(n)?e[t]():n},n.size=function(e){var t=e?e.length:0; -return typeof t=="number"?t:gn(e).length},n.some=F,n.sortedIndex=z,n.template=function(e,t,r){e||(e=""),r||(r={});var i,s,o=n.templateSettings,u=0,a=r.interpolate||o.interpolate||pt,l="__p+='",c=r.variable||o.variable,h=c;e.replace(RegExp((r.escape||o.escape||pt).source+"|"+a.source+"|"+(a===ht?ct:pt).source+"|"+(r.evaluate||o.evaluate||pt).source+"|$","g"),function(t,n,r,s,o,a){return r||(r=s),l+=e.slice(u,a).replace(vt,f),n&&(l+="'+__e("+n+")+'"),o&&(l+="';"+o+";__p+='"),r&&(l+="'+((__t=("+r+"))==null?'':__t)+'" -),i||(i=o||rt.test(n||r)),u=a+t.length,t}),l+="';\n",h||(c="obj",i?l="with("+c+"){"+l+"}":(r=RegExp("(\\(\\s*)"+c+"\\."+c+"\\b","g"),l=l.replace(ft,"$&"+c+".").replace(r,"$1__d"))),l=(i?l.replace(st,""):l).replace(ot,"$1").replace(ut,"$1;"),l="function("+c+"){"+(h?"":c+"||("+c+"={});")+"var __t,__p='',__e=_.escape"+(i?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":(h?"":",__d="+c+"."+c+"||"+c)+";")+l+"return __p}";try{s=Function("_","return "+l)(n)}catch(p){throw p.source= -l,p}return t?s(t):(s.source=l,s)},n.unescape=function(e){return null==e?"":(e+"").replace(it,d)},n.uniqueId=function(e){return(null==e?"":e+"")+ ++Z},n.all=A,n.any=F,n.detect=M,n.foldl=B,n.foldr=j,n.include=L,n.inject=B,cn(n,function(e,t){n.prototype[t]||(n.prototype[t]=function(){var t=[this.__wrapped__];return St.apply(t,arguments),e.apply(n,t)})}),n.first=I,n.last=function(e,t,n){if(e){var r=e.length;return null==t||n?e[r-1]:p(e,Ot(0,r-t))}},n.take=I,n.head=I,cn(n,function(e,t){n.prototype[t]|| -(n.prototype[t]=function(t,r){var i=e(this.__wrapped__,t,r);return null==t||r?i:new n(i)})}),n.VERSION="1.0.0-rc.3",n.prototype.toString=function(){return this.__wrapped__+""},n.prototype.value=J,n.prototype.valueOf=J,an(["join","pop","shift"],function(e){var t=G[e];n.prototype[e]=function(){return t.apply(this.__wrapped__,arguments)}}),an(["push","reverse","sort","unshift"],function(e){var t=G[e];n.prototype[e]=function(){return t.apply(this.__wrapped__,arguments),this}}),an(["concat","slice","splice" -],function(e){var t=G[e];n.prototype[e]=function(){var e=t.apply(this.__wrapped__,arguments);return new n(e)}}),$t&&an(["pop","shift","splice"],function(e){var t=G[e],r="splice"==e;n.prototype[e]=function(){var e=this.__wrapped__,i=t.apply(e,arguments);return 0===e.length&&delete e[0],r?new n(i):i}}),typeof define=="function"&&typeof define.amd=="object"&&define.amd?(e._=n,define(function(){return n})):K?typeof module=="object"&&module&&module.exports==K?(module.exports=n)._=n:K._=n:e._=n})(this); \ No newline at end of file diff --git a/test/test2/lib/helpers.coffee b/test/test2/lib/helpers.coffee deleted file mode 100644 index 16d7103fc4..0000000000 --- a/test/test2/lib/helpers.coffee +++ /dev/null @@ -1,45 +0,0 @@ -utils = require('utils') - -#enable this to get remote console output, useful for debug. -casper.on "remote.message", (msg)-> - casper.echo "Remote console: " + msg - -casper.helpers = (-> - baseUrl = 'http://localhost:3000' - getModel = (cb)-> - casper.waitFor( - -> #check function - casper.evaluate -> - user = window.DERBY.app.model.get('_user') - #wait till all fields get ready - check = (user?.stats?.exp?) - #assign to the window so we can access it later - window.userCopy = userCopy = - {} - #dirty hack to get all fields in the object - for k of user - userCopy[k] = user[k] - check - -> #run this if check passed - model = casper.evaluate -> - {user: window.userCopy} - cb null, model - ) - evalTest = (check, text, variables) -> - casper.waitFor( - -> #check function - casper.evaluate check, variables - -> #run this if check passed - casper.test.assert(true, text) - -> #run this if timeout - casper.test.assert(false, text) - ) - - { - casper: casper - baseUrl: baseUrl - playUrl: baseUrl + '/?play=1' - getModel: getModel - uid: Math.random().toString(36).substring(2) + Math.random().toString(36).substring(2) - evalTest: evalTest - })() diff --git a/test/test2/lib/lodash.min.js b/test/test2/lib/lodash.min.js deleted file mode 100644 index 40126c4a5d..0000000000 --- a/test/test2/lib/lodash.min.js +++ /dev/null @@ -1,42 +0,0 @@ -/*! - Lo-Dash 1.0.0-rc.3 lodash.com/license - Underscore.js 1.4.3 underscorejs.org/LICENSE -*/ -;(function(e,t){function n(e){if(e&&typeof e=="object"&&e.__wrapped__)return e;if(!(this instanceof n))return new n(e);this.__wrapped__=e}function r(e,t,n){t||(t=0);var r=e.length,i=r-t>=(n||tt);if(i)for(var s={},n=t-1;++nt||typeof e=="undefined")return 1;if( -ei;i++)r+="i='"+e.j[i]+"';if(","constructor"==e.j[i]&&(r+="!(f&&f.prototype===l)&&"),r+="h.call(l,i)){"+e.g+"}"}if(e.b||e.h)r+="}";return r+=e.c+";return t" -,n("e,h,j,k,p,n,s","return function("+t+"){"+r+"}")(u,Et,v,N,nn,At,xt)}function f(e){return"\\"+rn[e]}function l(e){return hn[e]}function c(e){return typeof e.toString!="function"&&typeof (e+"")=="string"}function h(){}function p(e,t,n){t||(t=0),typeof n=="undefined"&&(n=e?e.length:0);for(var r=-1,n=n-t||0,i=Array(0>n?0:n);++rn?Ot(0,i+n):n)||0;return typeof i=="number"?s=-1<(N(e)?e.indexOf(t,n):R(e,t,n)):an(e,function(e){if(++r>=n)return!(s=e===t)}),s} -function A(e,t,n){var r=!0,t=u(t,n);if(vn(e))for(var n=-1,i=e.length;++nr&&(r=n,a=e)});else for(;++sa&&(a=e[s]);return a}function H(e,t){return D(e,t+"")}function B(e,t,n,r){var i=3>arguments.length,t=u(t,r,et);if(vn(e)){var s=-1,o= -e.length;for(i&&(n=e[++s]);++sarguments.length;if(typeof s!="number")var a=gn(e),s=a.length;else Gt&&N(e)&&(i=e.split(""));return t=u(t,r,et),_(e,function(e,r,u){r=a?a[--s]:--s,n=o?(o=!1,i[r]):t(n,i[r],r,u)}),n}function F(e,t,n){var r,t=u(t,n);if(vn(e))for(var n=-1,i=e.length;++nn?Ot(0,i+n):n||0)-1;else if(n)return r=z(e,t),e[r]===t?r:-1;for(;++r>>1,n(e[r])R(a,c))(n||f)&&a.push(c),o.push(r)}return o}function X(e,t){return zt||Nt&&2|{(\/]|\[\D|\b(?:delete|in|instanceof|new|typeof|void)\b/,it=/&(?:amp|lt|gt|quot|#x27);/g,st=/\b__p\+='';/g,ot=/\b(__p\+=)''\+/g,ut=/(__e\(.*?\)|\b__t\))\+'';/g,at=/\w*$/,ft=/(?:__e|__t=)\(\s*(?![\d\s"']|this\.)/g -,lt=RegExp("^"+(Y.valueOf+"").replace(/[.*+?^=!:${}()|[\]\/\\]/g,"\\$&").replace(/valueOf|for [^\]]+/g,".+?")+"$"),ct=/\$\{((?:(?=\\?)\\?[\s\S])*?)}/g,ht=/<%=([\s\S]+?)%>/g,pt=/($^)/,dt=/[&<>"']/g,vt=/['\n\r\t\u2028\u2029\\]/g,mt="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" "),gt=Math.ceil,yt=G.concat,bt=Math.floor,wt=lt.test(wt=Object.getPrototypeOf)&&wt,Et=Y.hasOwnProperty,St=G.push,xt=Y.propertyIsEnumerable,Tt=Y.toString,Nt=lt.test(Nt= -p.bind)&&Nt,Ct=lt.test(Ct=Array.isArray)&&Ct,kt=e.isFinite,Lt=e.isNaN,At=lt.test(At=Object.keys)&&At,Ot=Math.max,Mt=Math.min,_t=Math.random,Dt="[object Arguments]",Pt="[object Array]",Ht="[object Boolean]",Bt="[object Date]",jt="[object Number]",Ft="[object Object]",It="[object RegExp]",qt="[object String]",Rt=!!e.attachEvent,Ut=Nt&&!/\n|true/.test(Nt+Rt),zt=Nt&&!Ut,Wt=At&&(Rt||Ut),Xt,Vt,$t=($t={0:1,length:1},G.splice.call($t,0,1),$t[0]),Jt=!0;(function(){function e(){this.x=1}var t=[];e.prototype= -{valueOf:1,y:1};for(var n in new e)t.push(n);for(n in arguments)Jt=!n;Xt=!/valueOf/.test(t),Vt="x"!=t[0]})(1);var Kt=arguments.constructor==Object,Qt=!v(arguments),Gt="xx"!="x"[0]+Object("x")[0];try{var Yt=("[object Object]",Tt.call(document)==Ft)}catch(Zt){}var en={"[object Function]":!1};en[Dt]=en[Pt]=en[Ht]=en[Bt]=en[jt]=en[Ft]=en[It]=en[qt]=!0;var tn={};tn[Pt]=Array,tn[Ht]=Boolean,tn[Bt]=Date,tn[Ft]=Object,tn[jt]=Number,tn[It]=RegExp,tn[qt]=String;var nn={"boolean":!1,"function":!0,object:!0, -number:!1,string:!1,"undefined":!1},rn={"\\":"\\","'":"'","\n":"n","\r":"r"," ":"t","\u2028":"u2028","\u2029":"u2029"};n.templateSettings={escape:/<%-([\s\S]+?)%>/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:ht,variable:""};var sn={a:"o,v,g",k:"for(var a=1,b=typeof g=='number'?2:arguments.length;a":">",'"':""","'":"'"},pn=w(hn),dn=a(sn,{g:"if(t[i]==null)"+sn.g}),vn=Ct||function(e){return Kt&&e instanceof Array||Tt.call(e)==Pt};S(/x/)&&(S=function(e){return e instanceof Function||"[object Function]"==Tt.call(e)});var mn=wt?function(e){if(!e||typeof e!="object")return!1;var t=e.valueOf,n=typeof t=="function"&&(n=wt(t))&&wt(n);return n?e==n||wt(e)==n&&!v(e):m(e) -}:m,gn=At?function(e){return typeof e=="function"&&xt.call(e,"prototype")?g(e):x(e)?At(e):[]}:g;n.after=function(e,t){return 1>e?t():function(){if(1>--e)return t.apply(this,arguments)}},n.assign=fn,n.bind=X,n.bindAll=function(e){for(var t=arguments,n=1R(f,l)){u&&f.push(l);for(var h=n;--h;)if(!(i[h]||(i[h]=r(t[h],0,100)))(l))continue e;a.push(l)}}return a},n.invert=w,n.invoke=function(e,t){var n=p(arguments,2),r=typeof t=="function",i=[];return _(e,function(e){i.push((r?t:e[t]).apply(e,n))}),i},n.keys=gn,n.map=D, -n.max=P,n.memoize=function(e,t){var n={};return function(){var r=t?t.apply(this,arguments):arguments[0];return Et.call(n,r)?n[r]:n[r]=e.apply(this,arguments)}},n.merge=C,n.min=function(e,t,n){var r=Infinity,s=-1,o=e?e.length:0,a=r;if(t||!vn(e))t=!t&&N(e)?i:u(t,n),an(e,function(e,n,i){n=t(e,n,i),nR(s,n,1))i[n]=e}),i},n.once=function(e){var t,n=!1;return function(){return n?t:(n=!0,t=e.apply(this,arguments),e=null,t)}},n.pairs=function(e){var t=[];return cn(e,function(e,n){t.push([n,e])}),t},n.partial=function(e){return o(e,p(arguments,1))},n.pick=function(e,t,n){var r={};if(typeof t!="function")for(var i=0,s=yt.apply(G,arguments),o=s.length;++i=f?(clearTimeout(o),o=null,u=a,i=e.apply(s,r)):o||(o=setTimeout(n,f)),i}},n.times=function(e,t,n){for(var e=+e||0,r=-1,i=Array(e);++rn?Ot(0,r+n):Mt(n,r-1))+1);r--;)if(e[r]===t)return r;return-1},n.mixin=$,n.noConflict=function(){return e._=nt,this},n.random=function(e,t){return null==e&&null==t&&(t=1),e=+e||0,null==t&&(t=e,e=0),e+bt(_t()*((+t||0)-e+1))},n.reduce=B,n.reduceRight=j,n.result=function(e,t){var n=e?e[t]:null;return S(n)?e[t]():n},n.size=function(e){var t=e?e.length:0; -return typeof t=="number"?t:gn(e).length},n.some=F,n.sortedIndex=z,n.template=function(e,t,r){e||(e=""),r||(r={});var i,s,o=n.templateSettings,u=0,a=r.interpolate||o.interpolate||pt,l="__p+='",c=r.variable||o.variable,h=c;e.replace(RegExp((r.escape||o.escape||pt).source+"|"+a.source+"|"+(a===ht?ct:pt).source+"|"+(r.evaluate||o.evaluate||pt).source+"|$","g"),function(t,n,r,s,o,a){return r||(r=s),l+=e.slice(u,a).replace(vt,f),n&&(l+="'+__e("+n+")+'"),o&&(l+="';"+o+";__p+='"),r&&(l+="'+((__t=("+r+"))==null?'':__t)+'" -),i||(i=o||rt.test(n||r)),u=a+t.length,t}),l+="';\n",h||(c="obj",i?l="with("+c+"){"+l+"}":(r=RegExp("(\\(\\s*)"+c+"\\."+c+"\\b","g"),l=l.replace(ft,"$&"+c+".").replace(r,"$1__d"))),l=(i?l.replace(st,""):l).replace(ot,"$1").replace(ut,"$1;"),l="function("+c+"){"+(h?"":c+"||("+c+"={});")+"var __t,__p='',__e=_.escape"+(i?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":(h?"":",__d="+c+"."+c+"||"+c)+";")+l+"return __p}";try{s=Function("_","return "+l)(n)}catch(p){throw p.source= -l,p}return t?s(t):(s.source=l,s)},n.unescape=function(e){return null==e?"":(e+"").replace(it,d)},n.uniqueId=function(e){return(null==e?"":e+"")+ ++Z},n.all=A,n.any=F,n.detect=M,n.foldl=B,n.foldr=j,n.include=L,n.inject=B,cn(n,function(e,t){n.prototype[t]||(n.prototype[t]=function(){var t=[this.__wrapped__];return St.apply(t,arguments),e.apply(n,t)})}),n.first=I,n.last=function(e,t,n){if(e){var r=e.length;return null==t||n?e[r-1]:p(e,Ot(0,r-t))}},n.take=I,n.head=I,cn(n,function(e,t){n.prototype[t]|| -(n.prototype[t]=function(t,r){var i=e(this.__wrapped__,t,r);return null==t||r?i:new n(i)})}),n.VERSION="1.0.0-rc.3",n.prototype.toString=function(){return this.__wrapped__+""},n.prototype.value=J,n.prototype.valueOf=J,an(["join","pop","shift"],function(e){var t=G[e];n.prototype[e]=function(){return t.apply(this.__wrapped__,arguments)}}),an(["push","reverse","sort","unshift"],function(e){var t=G[e];n.prototype[e]=function(){return t.apply(this.__wrapped__,arguments),this}}),an(["concat","slice","splice" -],function(e){var t=G[e];n.prototype[e]=function(){var e=t.apply(this.__wrapped__,arguments);return new n(e)}}),$t&&an(["pop","shift","splice"],function(e){var t=G[e],r="splice"==e;n.prototype[e]=function(){var e=this.__wrapped__,i=t.apply(e,arguments);return 0===e.length&&delete e[0],r?new n(i):i}}),typeof define=="function"&&typeof define.amd=="object"&&define.amd?(e._=n,define(function(){return n})):K?typeof module=="object"&&module&&module.exports==K?(module.exports=n)._=n:K._=n:e._=n})(this); \ No newline at end of file