Merge pull request #47 from FreeCodeCamp/bonfire-challenge-framework
Bonfire challenge framework
This commit is contained in:
@ -56,7 +56,7 @@ LINKEDIN_SECRET='LINKEDIN APP SECRET'
|
|||||||
```bash
|
```bash
|
||||||
|
|
||||||
# Seed your database with the challenges
|
# Seed your database with the challenges
|
||||||
node seed_data/seed_challenges.js
|
node seed_data/seed.js
|
||||||
|
|
||||||
# start the application
|
# start the application
|
||||||
gulp
|
gulp
|
||||||
|
8
app.js
8
app.js
@ -250,10 +250,10 @@ app.get(
|
|||||||
app.all('/account', passportConf.isAuthenticated);
|
app.all('/account', passportConf.isAuthenticated);
|
||||||
app.get('/account/api', userController.getAccountAngular);
|
app.get('/account/api', userController.getAccountAngular);
|
||||||
app.get('/bonfire', bonfireController.index);
|
app.get('/bonfire', bonfireController.index);
|
||||||
//app.get(
|
app.get(
|
||||||
// '/bonfire/:bonfireNumber',
|
'/bonfire/:bonfireNumber',
|
||||||
// bonfireController.returnBonfire
|
bonfireController.returnBonfire
|
||||||
//);
|
);
|
||||||
|
|
||||||
// Unique Check API route
|
// Unique Check API route
|
||||||
app.get('/api/checkUniqueUsername/:username', userController.checkUniqueUsername);
|
app.get('/api/checkUniqueUsername/:username', userController.checkUniqueUsername);
|
||||||
|
@ -1,68 +1,78 @@
|
|||||||
var _ = require('lodash'),
|
var _ = require('lodash'),
|
||||||
debug = require('debug')('freecc:cntr:bonfires');
|
debug = require('debug')('freecc:cntr:bonfires'),
|
||||||
// bonfire = require('./../models/Bonfire');
|
Bonfire = require('./../models/Bonfire');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bonfire controller
|
* Bonfire controller
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
var highestBonfireNumber = 10;
|
||||||
|
|
||||||
exports.index = function(req, res) {
|
exports.index = function(req, res) {
|
||||||
res.render('bonfire/bonfire.jade', {
|
res.render('bonfire/bonfire.jade', {
|
||||||
title: 'Learn to code with Bonfire'
|
title: 'Learn to code with Bonfire'
|
||||||
});
|
});
|
||||||
//Bonfire.find({}, null, { sort: { bonfireNumber: 1 } }, function(err, c) {
|
|
||||||
// if (err) {
|
Bonfire.find({}, null, { sort: { bonfireNumber: 1 } }, function(err, c) {
|
||||||
// debug('bonfire err: ', err);
|
if (err) {
|
||||||
// next(err);
|
debug('bonfire err: ', err);
|
||||||
// }
|
next(err);
|
||||||
//});
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
//exports.returnBonfire = function(req, res, next) {
|
exports.returnBonfire = function(req, res, next) {
|
||||||
// var bonfireNumber = parseInt(req.params.bonfireNumber) || 0;
|
var bonfireNumber = parseInt(req.params.bonfireNumber) || 0;
|
||||||
// var verbs = [
|
var verbs = [
|
||||||
// 'ACED',
|
'ACED',
|
||||||
// 'NAILED',
|
'NAILED',
|
||||||
// 'ROCKED',
|
'ROCKED',
|
||||||
// 'SCORCHED',
|
'SCORCHED',
|
||||||
// 'DEVASTATED',
|
'DEVASTATED',
|
||||||
// 'OWNED',
|
'OWNED',
|
||||||
// 'CRUSHED',
|
'CRUSHED',
|
||||||
// 'CONQUERED',
|
'CONQUERED',
|
||||||
// 'KILLED',
|
'KILLED',
|
||||||
// 'SHREDDED',
|
'SHREDDED',
|
||||||
// 'ANNIHILATED',
|
'ANNIHILATED',
|
||||||
// 'NUKED'
|
'NUKED'
|
||||||
// ];
|
];
|
||||||
// var phrases = [
|
var phrases = [
|
||||||
// "Shout it from on top of a mountain",
|
"Shout it from on top of a mountain",
|
||||||
// "Tell everyone and their dogs",
|
"Tell everyone and their dogs",
|
||||||
// "Show them. Show them all!",
|
"Show them. Show them all!",
|
||||||
// "Inspire your friends",
|
"Inspire your friends",
|
||||||
// "Tell the world of your greatness",
|
"Tell the world of your greatness",
|
||||||
// "Look accomplished on social media",
|
"Look accomplished on social media",
|
||||||
// "Share news of your grand endeavor",
|
"Share news of your grand endeavor",
|
||||||
// "Establish your alibi for the past two hours",
|
"Establish your alibi for the past two hours",
|
||||||
// "Prove to mom that computers aren't just for games"
|
"Prove to mom that computers aren't just for games"
|
||||||
// ];
|
];
|
||||||
// if (bonfireNumber > 53) { bonfireNumber = 0; }
|
|
||||||
// Bonfire.find({}, null, { sort: { bonfireNumber: 1 } }, function(err, c) {
|
if (bonfireNumber > highestBonfireNumber) { bonfireNumber = 0; }
|
||||||
// if (err) {
|
Bonfire.find({}, null, { sort: { bonfireNumber: 1 } }, function(err, bonfire) {
|
||||||
// debug('bonfire err: ', err);
|
debug(bonfire[bonfireNumber].challengeEntryPoint);
|
||||||
// next(err);
|
if (err) {
|
||||||
// }
|
debug('bonfire err: ', err);
|
||||||
// res.render('bonfires/show', {
|
next(err);
|
||||||
// //title: 'bonfire: ' + c[bonfireNumber].name,
|
}
|
||||||
// //name: c[bonfireNumber].name,
|
res.render('bonfire/show', {
|
||||||
// //video: c[bonfireNumber].video,
|
title: bonfire[bonfireNumber].name,
|
||||||
// //time: c[bonfireNumber].time,
|
name: bonfire[bonfireNumber].name,
|
||||||
// //steps: c[bonfireNumber].steps,
|
number: bonfire[bonfireNumber].bonfireNumber,
|
||||||
// //number: bonfireNumber,
|
difficulty: bonfire[bonfireNumber].difficulty,
|
||||||
// //categories: c[bonfireNumber].category,
|
description: bonfire[bonfireNumber].description,
|
||||||
// //cc: req.user ? req.user.bonfiresHash : undefined,
|
publicTests: bonfire[bonfireNumber].publicTests,
|
||||||
// //points: req.user ? req.user.points : undefined,
|
privateTests: bonfire[bonfireNumber].privateTests,
|
||||||
// //verb: verbs[Math.floor(Math.random() * verbs.length)],
|
challengeSeed: bonfire[bonfireNumber].challengeSeed,
|
||||||
// //phrase: phrases[Math.floor(Math.random() * phrases.length)],
|
challengeEntryPoint: bonfire[bonfireNumber].challengeEntryPoint,
|
||||||
// //bonfires: c
|
challengeEntryPointNegate: bonfire[bonfireNumber].challengeEntryPointNegate,
|
||||||
// });
|
|
||||||
// });
|
//cc: req.user ? req.user.bonfiresHash : undefined,
|
||||||
//};
|
//points: req.user ? req.user.points : undefined,
|
||||||
|
//verb: verbs[Math.floor(Math.random() * verbs.length)],
|
||||||
|
//phrase: phrases[Math.floor(Math.random() * phrases.length)],
|
||||||
|
bonfires: bonfire
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
@ -6,6 +6,8 @@ var _ = require('lodash'),
|
|||||||
debug = require('debug')('freecc:cntr:challenges'),
|
debug = require('debug')('freecc:cntr:challenges'),
|
||||||
Challenge = require('./../models/Challenge');
|
Challenge = require('./../models/Challenge');
|
||||||
|
|
||||||
|
var highestChallengeNumber = 53;
|
||||||
|
|
||||||
exports.returnChallenge = function(req, res, next) {
|
exports.returnChallenge = function(req, res, next) {
|
||||||
var challengeNumber = parseInt(req.params.challengeNumber) || 0;
|
var challengeNumber = parseInt(req.params.challengeNumber) || 0;
|
||||||
var verbs = [
|
var verbs = [
|
||||||
@ -33,7 +35,7 @@ exports.returnChallenge = function(req, res, next) {
|
|||||||
"Establish your alibi for the past two hours",
|
"Establish your alibi for the past two hours",
|
||||||
"Prove to mom that computers aren't just for games"
|
"Prove to mom that computers aren't just for games"
|
||||||
];
|
];
|
||||||
if (challengeNumber > 53) { challengeNumber = 0; }
|
if (challengeNumber > highestChallengeNumber) { challengeNumber = 0; }
|
||||||
Challenge.find({}, null, { sort: { challengeNumber: 1 } }, function(err, c) {
|
Challenge.find({}, null, { sort: { challengeNumber: 1 } }, function(err, c) {
|
||||||
if (err) {
|
if (err) {
|
||||||
debug('Challenge err: ', err);
|
debug('Challenge err: ', err);
|
||||||
|
@ -1,14 +1,27 @@
|
|||||||
var mongoose = require('mongoose');
|
var mongoose = require('mongoose');
|
||||||
var secrets = require('../config/secrets');
|
var secrets = require('../config/secrets');
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {exports.Schema}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
var bonfireSchema = new mongoose.Schema({
|
var bonfireSchema = new mongoose.Schema({
|
||||||
|
|
||||||
name: {
|
name: {
|
||||||
type: String,
|
type: String,
|
||||||
unique: true
|
unique: true
|
||||||
},
|
},
|
||||||
link: String,
|
difficulty: Number,
|
||||||
time: String,
|
description: Array,
|
||||||
bonfireNumber: Number
|
publicTests: Array,
|
||||||
|
privateTests: Array,
|
||||||
|
challengeSeed: String,
|
||||||
|
bonfireNumber: Number,
|
||||||
|
challengeEntryPoint: String,
|
||||||
|
challengeEntryPointNegate: String
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = mongoose.model('Bonfire', bonfireSchema);
|
module.exports = mongoose.model('Bonfire', bonfireSchema);
|
||||||
|
14
models/BonfireCompletion.js
Normal file
14
models/BonfireCompletion.js
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
var mongoose = require('mongoose');
|
||||||
|
var secrets = require('../config/secrets');
|
||||||
|
|
||||||
|
var bonfireCompletionSchema = new mongoose.Schema({
|
||||||
|
dateCompleted: Number,
|
||||||
|
completedWith: String,
|
||||||
|
bonfireNumber: {
|
||||||
|
bonfireNumber: Number,
|
||||||
|
bonfireId: String
|
||||||
|
},
|
||||||
|
solution: String
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = mongoose.model('BonfireCompletion', bonfireCompletionSchema);
|
745
models/User.js
745
models/User.js
@ -3,356 +3,357 @@ var crypto = require('crypto');
|
|||||||
var mongoose = require('mongoose');
|
var mongoose = require('mongoose');
|
||||||
|
|
||||||
var userSchema = new mongoose.Schema({
|
var userSchema = new mongoose.Schema({
|
||||||
email: {
|
email: {
|
||||||
type: String,
|
type: String,
|
||||||
lowercase: true,
|
lowercase: true,
|
||||||
unique: true,
|
unique: true,
|
||||||
trim: true,
|
trim: true,
|
||||||
sparse: true
|
sparse: true
|
||||||
},
|
},
|
||||||
password: String,
|
password: String,
|
||||||
facebook: String,
|
facebook: String,
|
||||||
twitter: String,
|
twitter: String,
|
||||||
google: String,
|
google: String,
|
||||||
github: String,
|
github: String,
|
||||||
linkedin: String,
|
linkedin: String,
|
||||||
tokens: Array,
|
tokens: Array,
|
||||||
points: {
|
points: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
challengesCompleted: { type: Array, default: [] },
|
challengesCompleted: { type: Array, default: [] },
|
||||||
challengesHash: {
|
challengesHash: {
|
||||||
0: {
|
0: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
1: {
|
1: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
2: {
|
2: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
3: {
|
3: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
4: {
|
4: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
5: {
|
5: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
6: {
|
6: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
7: {
|
7: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
8: {
|
8: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
9: {
|
9: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
10: {
|
10: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
11: {
|
11: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
12: {
|
12: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
13: {
|
13: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
14: {
|
14: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
15: {
|
15: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
16: {
|
16: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
17: {
|
17: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
18: {
|
18: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
19: {
|
19: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
20: {
|
20: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
21: {
|
21: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
22: {
|
22: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
23: {
|
23: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
24: {
|
24: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
25: {
|
25: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
26: {
|
26: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
27: {
|
27: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
28: {
|
28: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
29: {
|
29: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
30: {
|
30: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
31: {
|
31: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
32: {
|
32: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
33: {
|
33: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
34: {
|
34: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
35: {
|
35: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
36: {
|
36: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
37: {
|
37: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
38: {
|
38: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
39: {
|
39: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
40: {
|
40: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
41: {
|
41: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
42: {
|
42: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
43: {
|
43: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
44: {
|
44: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
45: {
|
45: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
46: {
|
46: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
47: {
|
47: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
48: {
|
48: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
49: {
|
49: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
50: {
|
50: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
51: {
|
51: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
52: {
|
52: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
53: {
|
53: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
54: {
|
54: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
55: {
|
55: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
56: {
|
56: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
57: {
|
57: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
58: {
|
58: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
59: {
|
59: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
profile: {
|
profile: {
|
||||||
username: {
|
username: {
|
||||||
type: String,
|
type: String,
|
||||||
unique: true,
|
unique: true,
|
||||||
sparse: true,
|
sparse: true,
|
||||||
lowercase: true,
|
lowercase: true,
|
||||||
trim: true
|
trim: true
|
||||||
},
|
},
|
||||||
bio: {
|
bio: {
|
||||||
type: String,
|
type: String,
|
||||||
defaults: ''
|
defaults: ''
|
||||||
},
|
},
|
||||||
name: {
|
name: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: ''
|
||||||
},
|
},
|
||||||
gender: {
|
gender: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: ''
|
||||||
},
|
},
|
||||||
location: {
|
location: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: ''
|
||||||
},
|
},
|
||||||
picture: {
|
picture: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: ''
|
||||||
},
|
},
|
||||||
linkedinProfile: {
|
linkedinProfile: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: ''
|
||||||
},
|
},
|
||||||
githubProfile: {
|
githubProfile: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: ''
|
||||||
},
|
},
|
||||||
coderbyteProfile: {
|
coderbyteProfile: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: ''
|
||||||
},
|
},
|
||||||
codepenProfile: {
|
codepenProfile: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: ''
|
||||||
},
|
},
|
||||||
twitterHandle: {
|
twitterHandle: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
portfolio: {
|
portfolio: {
|
||||||
website1Link: {
|
website1Link: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: ''
|
||||||
},
|
},
|
||||||
website1Title: {
|
website1Title: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: ''
|
||||||
},
|
},
|
||||||
website1Image: {
|
website1Image: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: ''
|
||||||
},
|
},
|
||||||
website2Link: {
|
website2Link: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: ''
|
||||||
},
|
},
|
||||||
website2Title: {
|
website2Title: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: ''
|
||||||
},
|
},
|
||||||
website2Image: {
|
website2Image: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: ''
|
||||||
},
|
},
|
||||||
website3Link: {
|
website3Link: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: ''
|
||||||
},
|
},
|
||||||
website3Title: {
|
website3Title: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: ''
|
||||||
},
|
},
|
||||||
website3Image: {
|
website3Image: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
resetPasswordToken: String,
|
resetPasswordToken: String,
|
||||||
resetPasswordExpires: Date
|
resetPasswordExpires: Date,
|
||||||
|
bonfires: Array
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -360,19 +361,19 @@ var userSchema = new mongoose.Schema({
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
userSchema.pre('save', function(next) {
|
userSchema.pre('save', function(next) {
|
||||||
var user = this;
|
var user = this;
|
||||||
|
|
||||||
if (!user.isModified('password')) { return next(); }
|
if (!user.isModified('password')) { return next(); }
|
||||||
|
|
||||||
bcrypt.genSalt(5, function(err, salt) {
|
bcrypt.genSalt(5, function(err, salt) {
|
||||||
if (err) { return next(err); }
|
if (err) { return next(err); }
|
||||||
|
|
||||||
bcrypt.hash(user.password, salt, null, function(err, hash) {
|
bcrypt.hash(user.password, salt, null, function(err, hash) {
|
||||||
if (err) { return next(err); }
|
if (err) { return next(err); }
|
||||||
user.password = hash;
|
user.password = hash;
|
||||||
next();
|
next();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -380,10 +381,10 @@ userSchema.pre('save', function(next) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
userSchema.methods.comparePassword = function(candidatePassword, cb) {
|
userSchema.methods.comparePassword = function(candidatePassword, cb) {
|
||||||
bcrypt.compare(candidatePassword, this.password, function(err, isMatch) {
|
bcrypt.compare(candidatePassword, this.password, function(err, isMatch) {
|
||||||
if (err) { return cb(err); }
|
if (err) { return cb(err); }
|
||||||
cb(null, isMatch);
|
cb(null, isMatch);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -391,18 +392,18 @@ userSchema.methods.comparePassword = function(candidatePassword, cb) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
userSchema.methods.gravatar = function(size) {
|
userSchema.methods.gravatar = function(size) {
|
||||||
if (!size) { size = 200; }
|
if (!size) { size = 200; }
|
||||||
|
|
||||||
if (!this.email) {
|
if (!this.email) {
|
||||||
return 'https://gravatar.com/avatar/?s=' + size + '&d=retro';
|
return 'https://gravatar.com/avatar/?s=' + size + '&d=retro';
|
||||||
}
|
}
|
||||||
|
|
||||||
var md5 = crypto
|
var md5 = crypto
|
||||||
.createHash('md5')
|
.createHash('md5')
|
||||||
.update(this.email)
|
.update(this.email)
|
||||||
.digest('hex');
|
.digest('hex');
|
||||||
|
|
||||||
return 'https://gravatar.com/avatar/' + md5 + '?s=' + size + '&d=retro';
|
return 'https://gravatar.com/avatar/' + md5 + '?s=' + size + '&d=retro';
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = mongoose.model('User', userSchema);
|
module.exports = mongoose.model('User', userSchema);
|
||||||
|
@ -569,6 +569,13 @@ div.CodeMirror-scroll {
|
|||||||
text-size: 250px;
|
text-size: 250px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.bonfire-instructions p {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
.bonfire-instructions {
|
||||||
|
margin-bottom: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
//uncomment this to see the dimensions of all elements outlined in red
|
//uncomment this to see the dimensions of all elements outlined in red
|
||||||
//* {
|
//* {
|
||||||
// border-color: red;
|
// border-color: red;
|
||||||
|
228
public/js/lib/bonfire/bonfireFramework.js
Normal file
228
public/js/lib/bonfire/bonfireFramework.js
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
var widgets = [];
|
||||||
|
var myCodeMirror = CodeMirror.fromTextArea(document.getElementById("codeEditor"), {
|
||||||
|
lineNumbers: true,
|
||||||
|
mode: "javascript",
|
||||||
|
theme: 'monokai',
|
||||||
|
runnable: true,
|
||||||
|
lint: true,
|
||||||
|
matchBrackets: true,
|
||||||
|
autoCloseBrackets: true,
|
||||||
|
cursorHeight: 1,
|
||||||
|
scrollbarStyle: 'null',
|
||||||
|
lineWrapping: true,
|
||||||
|
gutters: ["CodeMirror-lint-markers"],
|
||||||
|
onKeyEvent: doLinting,
|
||||||
|
extraKeys : {
|
||||||
|
"Ctrl-Enter" : function() {
|
||||||
|
bonfireExecute();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
var editor = myCodeMirror;
|
||||||
|
|
||||||
|
|
||||||
|
// Default value for editor if one isn't provided in (i.e. a challenge)
|
||||||
|
var nonChallengeValue = '/*Welcome to Bonfire, Free Code Camp\'s future CoderByte replacement.\n' +
|
||||||
|
'Please feel free to use Bonfire as an in-browser playground and linting tool.\n' +
|
||||||
|
'Note that you can also write tests using Chai.js\n' +
|
||||||
|
' by using the keywords assert and expect */\n\n' +
|
||||||
|
'function test() {\n' +
|
||||||
|
' assert(2 !== 3, "2 is not equal to 3");\n' +
|
||||||
|
' return [1,2,3].map(function(elem) {\n' +
|
||||||
|
' return elem * elem;\n' +
|
||||||
|
' });\n' +
|
||||||
|
'}\n' +
|
||||||
|
'expect(test()).to.be.a("array");\n\n' +
|
||||||
|
'assert.deepEqual(test(), [1,4,9]);\n\n' +
|
||||||
|
'test();';
|
||||||
|
|
||||||
|
var codeOutput = CodeMirror.fromTextArea(document.getElementById("codeOutput"), {
|
||||||
|
lineNumbers: false,
|
||||||
|
mode: "text",
|
||||||
|
theme: 'monokai',
|
||||||
|
readOnly: 'nocursor',
|
||||||
|
lineWrapping: true
|
||||||
|
});
|
||||||
|
codeOutput.setValue('/**\n' +
|
||||||
|
' * Your output will go here. Console.log() -type statements\n' +
|
||||||
|
' * will appear in your browser\'s javascript console.\n' +
|
||||||
|
' */');
|
||||||
|
codeOutput.setSize("100%", "100%");
|
||||||
|
var info = editor.getScrollInfo();
|
||||||
|
var after = editor.charCoords({line: editor.getCursor().line + 1, ch: 0}, "local").top;
|
||||||
|
if (info.top + info.clientHeight < after)
|
||||||
|
editor.scrollTo(null, after - info.clientHeight + 3);
|
||||||
|
|
||||||
|
var editorValue;
|
||||||
|
|
||||||
|
|
||||||
|
var challengeSeed = challengeSeed || null;
|
||||||
|
var publicTests = publicTests || [];
|
||||||
|
var privateTests = privateTests || [];
|
||||||
|
var challengeEntryPoint = challengeEntryPoint || null;
|
||||||
|
var challengeEntryPointNegate = challengeEntryPointNegate || null;
|
||||||
|
|
||||||
|
|
||||||
|
if (challengeSeed !== null) {
|
||||||
|
editorValue = challengeSeed + '\n\n' + challengeEntryPoint;
|
||||||
|
} else {
|
||||||
|
editorValue = nonChallengeValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
myCodeMirror.setValue(editorValue);
|
||||||
|
|
||||||
|
function doLinting () {
|
||||||
|
editor.operation(function () {
|
||||||
|
for (var i = 0; i < widgets.length; ++i)
|
||||||
|
editor.removeLineWidget(widgets[i]);
|
||||||
|
widgets.length = 0;
|
||||||
|
JSHINT(editor.getValue());
|
||||||
|
for (var i = 0; i < JSHINT.errors.length; ++i) {
|
||||||
|
var err = JSHINT.errors[i];
|
||||||
|
if (!err) continue;
|
||||||
|
var msg = document.createElement("div");
|
||||||
|
var icon = msg.appendChild(document.createElement("span"));
|
||||||
|
icon.innerHTML = "!!";
|
||||||
|
icon.className = "lint-error-icon";
|
||||||
|
msg.appendChild(document.createTextNode(err.reason));
|
||||||
|
msg.className = "lint-error";
|
||||||
|
widgets.push(editor.addLineWidget(err.line - 1, msg, {
|
||||||
|
coverGutter: false,
|
||||||
|
noHScroll: true
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
$('#submitButton').on('click', function () {
|
||||||
|
bonfireExecute();
|
||||||
|
});
|
||||||
|
|
||||||
|
function bonfireExecute() {
|
||||||
|
tests = null;
|
||||||
|
$('#codeOutput').empty();
|
||||||
|
var userJavaScript = myCodeMirror.getValue();
|
||||||
|
userJavaScript = removeComments(userJavaScript);
|
||||||
|
userJavaScript = scrapeTests(userJavaScript);
|
||||||
|
submit(userJavaScript, function(cls, message) {
|
||||||
|
if (cls) {
|
||||||
|
codeOutput.setValue(message.error);
|
||||||
|
runTests('Error', null);
|
||||||
|
} else {
|
||||||
|
codeOutput.setValue(message.output);
|
||||||
|
message.input = removeLogs(message.input);
|
||||||
|
runTests(null, message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
var replaceQuotesInTests = function() {
|
||||||
|
tests.forEach(function(elt, ix, arr) {
|
||||||
|
arr[ix].text = arr[ix].text.replace(/\"/g,'\'');
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
var tests;
|
||||||
|
var testSalt = Math.random();
|
||||||
|
|
||||||
|
|
||||||
|
var scrapeTests = function(userJavaScript) {
|
||||||
|
|
||||||
|
for (var i = 0; i < publicTests.length; i++) {
|
||||||
|
userJavaScript += '\n' + publicTests[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < privateTests.length; i++) {
|
||||||
|
userJavaScript += '\n' + privateTests[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
var counter = 0;
|
||||||
|
var regex = new RegExp(/(expect(\s+)?\(.*\;)|(assert(\s+)?\(.*\;)|(assert\.\w.*\;)|(.*\.should\..*\;)/);
|
||||||
|
var match = regex.exec(userJavaScript);
|
||||||
|
while (match != null) {
|
||||||
|
var replacement = '//' + counter + testSalt;
|
||||||
|
userJavaScript = userJavaScript.substring(0, match.index)
|
||||||
|
+ replacement
|
||||||
|
+ userJavaScript.substring(match.index + match[0].length);
|
||||||
|
|
||||||
|
if (!tests) tests = [];
|
||||||
|
tests.push({"text": match[0], "line": counter, "err": null});
|
||||||
|
counter++;
|
||||||
|
match = regex.exec(userJavaScript);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tests) replaceQuotesInTests();
|
||||||
|
return userJavaScript;
|
||||||
|
};
|
||||||
|
|
||||||
|
function removeComments(userJavaScript) {
|
||||||
|
var regex = new RegExp(/(\/\*[^(\*\/)]*\*\/)|\/\/[^\n]*/g);
|
||||||
|
return userJavaScript.replace(regex, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeLogs(userJavaScript) {
|
||||||
|
return userJavaScript.replace(/(console\.[\w]+\s*\(.*\;)/g, '');
|
||||||
|
return userJavaScript;
|
||||||
|
}
|
||||||
|
|
||||||
|
var pushed = false;
|
||||||
|
var createTestDisplay = function() {
|
||||||
|
if (pushed) {
|
||||||
|
tests.pop();
|
||||||
|
}
|
||||||
|
for (var i = 0; i < tests.length;i++) {
|
||||||
|
var test = tests[i];
|
||||||
|
var testDoc = document.createElement("li");
|
||||||
|
$(testDoc)
|
||||||
|
.addClass('list-group-item')
|
||||||
|
.addClass('well img-rounded')
|
||||||
|
.addClass('well-sm')
|
||||||
|
if (test.err != null) {
|
||||||
|
$(testDoc)
|
||||||
|
.html(test.text + "\n" + test.err)
|
||||||
|
.css("background-color", 'rgba(255,0,0,.2)')
|
||||||
|
.prependTo($('#testSuite'));
|
||||||
|
} else {
|
||||||
|
$(testDoc)
|
||||||
|
.html(test.text)
|
||||||
|
.css('background-color', 'rgba(0,255,0,.2)')
|
||||||
|
.appendTo($('#testSuite'));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
var assert = chai.assert;
|
||||||
|
var expect = chai.expect;
|
||||||
|
var should = chai.should();
|
||||||
|
|
||||||
|
var reassembleTest = function(test, data) {
|
||||||
|
var lineNum = test.line;
|
||||||
|
var regexp = new RegExp("\/\/" + lineNum + testSalt);
|
||||||
|
return data.input.replace(regexp, test.text);
|
||||||
|
};
|
||||||
|
var runTests = function(err, data) {
|
||||||
|
pushed = false;
|
||||||
|
$('#testSuite').children().remove();
|
||||||
|
if (err && tests.length > 0) {
|
||||||
|
tests = [{text:"Program Execution Failure", err: "No tests were run."}];
|
||||||
|
createTestDisplay();
|
||||||
|
} else if (tests) {
|
||||||
|
tests.push(false);
|
||||||
|
pushed = true;
|
||||||
|
tests.forEach(function(test, ix, arr){
|
||||||
|
try {
|
||||||
|
if (test) {
|
||||||
|
var output = eval(reassembleTest(test, data));
|
||||||
|
}
|
||||||
|
} catch(error) {
|
||||||
|
|
||||||
|
arr[ix].err = error.name + ":" + error.message;
|
||||||
|
} finally {
|
||||||
|
if (!test) {
|
||||||
|
createTestDisplay();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
@ -46,6 +46,7 @@ var api = {
|
|||||||
reset();
|
reset();
|
||||||
} else {
|
} else {
|
||||||
print(null, data);
|
print(null, data);
|
||||||
|
reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -66,18 +67,20 @@ var requests;
|
|||||||
// (re)initializes the plugin
|
// (re)initializes the plugin
|
||||||
var reset = function() {
|
var reset = function() {
|
||||||
requests = 0;
|
requests = 0;
|
||||||
plugin = new jailed.Plugin(path+'plugin_v0.1.1.js', api);
|
plugin = new jailed.Plugin(path+'plugin_v0.1.2.js', api);
|
||||||
plugin.whenDisconnected( function() {
|
plugin.whenDisconnected( function() {
|
||||||
// give some time to handle the last responce
|
// give some time to handle the last responce
|
||||||
setTimeout( function() {
|
setTimeout( function() {
|
||||||
endLoading();
|
endLoading();
|
||||||
codeOutput.setValue('Infinite loop detected!');
|
console.log("resetting on fatal plugin error");
|
||||||
|
codeOutput.setValue('Infinite loop or fatal error!');
|
||||||
reset();
|
reset();
|
||||||
}, 10);
|
}, 10);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// initialize everything
|
// initialize everything
|
||||||
var plugin = null;
|
var plugin = null;
|
||||||
|
|
@ -1,378 +0,0 @@
|
|||||||
var widgets = [];
|
|
||||||
var myCodeMirror = CodeMirror.fromTextArea(document.getElementById("codeEditor"), {
|
|
||||||
lineNumbers: true,
|
|
||||||
mode: "javascript",
|
|
||||||
theme: 'monokai',
|
|
||||||
runnable: true,
|
|
||||||
lint: true,
|
|
||||||
matchBrackets: true,
|
|
||||||
autoCloseBrackets: true,
|
|
||||||
cursorHeight: 0.85,
|
|
||||||
scrollbarStyle: 'null',
|
|
||||||
lineWrapping: true,
|
|
||||||
gutters: ["CodeMirror-lint-markers"],
|
|
||||||
onKeyEvent: doLinting,
|
|
||||||
extraKeys : {
|
|
||||||
"Ctrl-Enter" : function() {
|
|
||||||
bonfireExecute();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
var editor = myCodeMirror;
|
|
||||||
myCodeMirror.setValue('/*Welcome to Bonfire, Free Code Camp\'s future CoderByte replacement.\n' +
|
|
||||||
'Please feel free to use Bonfire as an in-browser playground and linting tool.\n' +
|
|
||||||
'Note that you can also write tests using Chai.js by using the keywords assert and expect */\n\n' +
|
|
||||||
'function test() {\n' +
|
|
||||||
' assert(2 !== 3, "2 is not equal to 3");\n' +
|
|
||||||
' return [1,2,3].map(function(elem) {\n' +
|
|
||||||
' return elem * elem;\n' +
|
|
||||||
' });\n' +
|
|
||||||
'}\n' +
|
|
||||||
'expect(test()).to.be.a("array");\n\n' +
|
|
||||||
'assert.deepEqual(test(), [1,4,9]);\n\n' +
|
|
||||||
'test();');
|
|
||||||
//myCodeMirror.setSize("100%", "100%");
|
|
||||||
|
|
||||||
var codeOutput = CodeMirror.fromTextArea(document.getElementById("codeOutput"), {
|
|
||||||
lineNumbers: false,
|
|
||||||
mode: "text",
|
|
||||||
theme: 'monokai',
|
|
||||||
readOnly: 'nocursor',
|
|
||||||
lineWrapping: true
|
|
||||||
});
|
|
||||||
codeOutput.setValue('/**\n' +
|
|
||||||
' * Your output will go here. Console.log() -type statements\n' +
|
|
||||||
' * will appear in your browser\'s javascript console.\n' +
|
|
||||||
' */');
|
|
||||||
codeOutput.setSize("100%", "100%");
|
|
||||||
var info = editor.getScrollInfo();
|
|
||||||
var after = editor.charCoords({line: editor.getCursor().line + 1, ch: 0}, "local").top;
|
|
||||||
if (info.top + info.clientHeight < after)
|
|
||||||
editor.scrollTo(null, after - info.clientHeight + 3);
|
|
||||||
var doLinting = function () {
|
|
||||||
editor.operation(function () {
|
|
||||||
for (var i = 0; i < widgets.length; ++i)
|
|
||||||
editor.removeLineWidget(widgets[i]);
|
|
||||||
widgets.length = 0;
|
|
||||||
JSHINT(editor.getValue());
|
|
||||||
for (var i = 0; i < JSHINT.errors.length; ++i) {
|
|
||||||
var err = JSHINT.errors[i];
|
|
||||||
if (!err) continue;
|
|
||||||
var msg = document.createElement("div");
|
|
||||||
var icon = msg.appendChild(document.createElement("span"));
|
|
||||||
icon.innerHTML = "!!";
|
|
||||||
icon.className = "lint-error-icon";
|
|
||||||
msg.appendChild(document.createTextNode(err.reason));
|
|
||||||
msg.className = "lint-error";
|
|
||||||
widgets.push(editor.addLineWidget(err.line - 1, msg, {
|
|
||||||
coverGutter: false,
|
|
||||||
noHScroll: true
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
var replaceQuotesInTests = function() {
|
|
||||||
tests.forEach(function(elt, ix, arr) {
|
|
||||||
arr[ix].text = arr[ix].text.replace(/\"/g,'\'');
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
var tests;
|
|
||||||
var testSalt = Math.random();
|
|
||||||
|
|
||||||
var scrapeTests = function(userJavaScript) {
|
|
||||||
var counter = 0;
|
|
||||||
var regex = new RegExp(/(expect(\s+)?\(.*\;)|(assert(\s+)?\(.*\;)|(assert\.\w.*\;)/);
|
|
||||||
var match = regex.exec(userJavaScript);
|
|
||||||
while (match != null) {
|
|
||||||
var replacement = '//' + counter + testSalt;
|
|
||||||
userJavaScript = userJavaScript.substring(0, match.index)
|
|
||||||
+ replacement
|
|
||||||
+ userJavaScript.substring(match.index + match[0].length);
|
|
||||||
|
|
||||||
if (!tests) tests = [];
|
|
||||||
tests.push({"text": match[0], "line": counter, "err": null});
|
|
||||||
counter++;
|
|
||||||
match = regex.exec(userJavaScript);
|
|
||||||
}
|
|
||||||
replaceQuotesInTests();
|
|
||||||
return userJavaScript;
|
|
||||||
};
|
|
||||||
|
|
||||||
$('#submitButton').on('click', function () {
|
|
||||||
bonfireExecute();
|
|
||||||
});
|
|
||||||
|
|
||||||
function bonfireExecute() {
|
|
||||||
tests = undefined;
|
|
||||||
$('#codeOutput').empty();
|
|
||||||
var userJavaScript = myCodeMirror.getValue();
|
|
||||||
userJavaScript = scrapeTests(userJavaScript);
|
|
||||||
submit(userJavaScript, function(cls, message) {
|
|
||||||
if (cls) {
|
|
||||||
codeOutput.setValue(message.error);
|
|
||||||
runTests('Error', null);
|
|
||||||
} else {
|
|
||||||
codeOutput.setValue(message.output);
|
|
||||||
runTests(null, message);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
var pushed = false;
|
|
||||||
var createTestDisplay = function() {
|
|
||||||
if (pushed) {
|
|
||||||
tests.pop();
|
|
||||||
}
|
|
||||||
for (var i = 0; i < tests.length;i++) {
|
|
||||||
var test = tests[i];
|
|
||||||
var testDoc = document.createElement("li");
|
|
||||||
$(testDoc)
|
|
||||||
.addClass('list-group-item')
|
|
||||||
.addClass('well img-rounded')
|
|
||||||
.addClass('well-sm')
|
|
||||||
if (test.err != null) {
|
|
||||||
$(testDoc)
|
|
||||||
.html(test.text + "\n" + test.err)
|
|
||||||
.css("background-color", 'rgba(255,0,0,.2)')
|
|
||||||
.prependTo($('#testSuite'));
|
|
||||||
} else {
|
|
||||||
$(testDoc)
|
|
||||||
.html(test.text)
|
|
||||||
.css('background-color', 'rgba(0,255,0,.2)')
|
|
||||||
.appendTo($('#testSuite'));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
var assert = chai.assert;
|
|
||||||
var expect = chai.expect;
|
|
||||||
var reassembleTest = function(test, data) {
|
|
||||||
var lineNum = test.line;
|
|
||||||
var regexp = new RegExp("\/\/" + lineNum + testSalt);
|
|
||||||
return data.input.replace(regexp, test.text);
|
|
||||||
};
|
|
||||||
var runTests = function(err, data) {
|
|
||||||
pushed = false;
|
|
||||||
$('#testSuite').children().remove();
|
|
||||||
if (err && tests) {
|
|
||||||
tests = [{text:"Program Execution Failure", err: "No tests were run."}];
|
|
||||||
createTestDisplay();
|
|
||||||
} else if (tests) {
|
|
||||||
tests.push(false);
|
|
||||||
pushed = true;
|
|
||||||
tests.forEach(function(test, ix, arr){
|
|
||||||
try {
|
|
||||||
if (test) {
|
|
||||||
var output = eval(reassembleTest(test, data));
|
|
||||||
}
|
|
||||||
} catch(error) {
|
|
||||||
console.log(error);
|
|
||||||
arr[ix].err = error.name + ":" + error.message;
|
|
||||||
console.log(arr);
|
|
||||||
} finally {
|
|
||||||
if (!test) {
|
|
||||||
//window.setTimeout(function() {createTestDisplay()},2000);
|
|
||||||
createTestDisplay();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// var assert = chai.assert;
|
|
||||||
// var testResults = [];
|
|
||||||
// $('#runTests').on('click', function () {
|
|
||||||
// clearTestOutput();
|
|
||||||
// var testCaseList = [],
|
|
||||||
// jsCode = myCodeMirror.getValue();
|
|
||||||
// getTestSuite().each(function () {
|
|
||||||
// testCaseList.push([$(this).data("input"), $(this).data("output"), $(this)]);
|
|
||||||
// });
|
|
||||||
// testCaseList.forEach(function (input) {
|
|
||||||
// var testCode = jsCode + "\n\n" + input[0] + ";";
|
|
||||||
// //TODO use plugin for this with the rest as a callback?
|
|
||||||
// var output = eval(testCode);
|
|
||||||
// testEquality(output, input);
|
|
||||||
// });
|
|
||||||
// // some timeout here?
|
|
||||||
// if (testResults.length === testCaseList.length) {
|
|
||||||
// var sum = testResults.reduce(function (a, b) {
|
|
||||||
// return a + b
|
|
||||||
// });
|
|
||||||
// prependTestOutput("======Testing========\n" + Math.round(100 * sum / testResults.length) + "% tests passed\n");
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// var testEquality = function (output, input) {
|
|
||||||
// try {
|
|
||||||
// switch (typeof output) {
|
|
||||||
// case 'object':
|
|
||||||
// assert.deepEqual(output, input[1]);
|
|
||||||
// break;
|
|
||||||
// case 'string':
|
|
||||||
// assert(output.localeCompare(input[1]));
|
|
||||||
// break
|
|
||||||
// default:
|
|
||||||
// assert.equal(output, input[1]);
|
|
||||||
// }
|
|
||||||
// appendTestOutput("\n" + createTestString(input[0], input[1]) + "\nTest passed!\n");
|
|
||||||
// input[2].css("background-color", "rgba(0,255,0,.2)");
|
|
||||||
// testResults.push(1);
|
|
||||||
// } catch (err) {
|
|
||||||
// input[2].css("background-color", "rgba(255,0,0,.2)");
|
|
||||||
// appendTestOutput(createTestString(input[0], input[1]));
|
|
||||||
// appendTestOutput("Test failed: \nOutput was: " + output + "\nType of output was: " + (typeof output));
|
|
||||||
// testResults.push(0);
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
//$('#sideBySide').on('click', function () {
|
|
||||||
// var main = $('#mainEditorPanel');
|
|
||||||
// if (main.hasClass('col-md-12')) {
|
|
||||||
// replaceColClz(main, 'md', 12, 6);
|
|
||||||
// replaceColClz(main, 'sm', 12, 6);
|
|
||||||
// $(this).text("Original Layout")
|
|
||||||
// } else {
|
|
||||||
// replaceColClz(main, 'md', 6, 12);
|
|
||||||
// replaceColClz(main, 'sm', 6, 12);
|
|
||||||
// $(this).text("Tests side by side")
|
|
||||||
// }
|
|
||||||
//});
|
|
||||||
//var replaceColClz = function (elt, size, oldVal, newVal) {
|
|
||||||
// elt.removeClass('col-' + size + '-' + oldVal);
|
|
||||||
// elt.addClass('col-' + size + '-' + newVal);
|
|
||||||
//};
|
|
||||||
//var getTestSuite = function () {
|
|
||||||
// return $('#testSuite').find('li');
|
|
||||||
//};
|
|
||||||
//var clearTestOutput = function () {
|
|
||||||
// testOutput.setValue("");
|
|
||||||
//};
|
|
||||||
var appendTestOutput = function (msg) {
|
|
||||||
writeToTest(msg, CodeMirror.Pos(editor.lastLine()));
|
|
||||||
};
|
|
||||||
var prependTestOutput = function (msg) {
|
|
||||||
writeToTest(msg, CodeMirror.Pos(editor.firstLine()));
|
|
||||||
};
|
|
||||||
var writeToTest = function (msg, location) {
|
|
||||||
testOutput.replaceRange("\n" + msg, location);
|
|
||||||
};
|
|
||||||
//$('#addTest').on('click', function () {
|
|
||||||
// var functionName = $('#testFunctionName option:selected').text();
|
|
||||||
// var inputs = [];
|
|
||||||
// var output;
|
|
||||||
// $('#testInputs').find('input').each(function () {
|
|
||||||
// if ($(this).val() != null && $(this).val().length !== 0) {
|
|
||||||
// inputs.push($(this).val());
|
|
||||||
// } else {
|
|
||||||
// //var keepGoing = prompt("You have submitted a test with empty input. Enter yes to continue.");
|
|
||||||
// if (/yes/.test(keepGoing.toLowerCase())) {
|
|
||||||
// inputs.push($(this).val());
|
|
||||||
// } else {
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// output = $('#testOutputs').find('input').val();
|
|
||||||
// var functionCall = functionName + "(" + inputs.join(",") + ")";
|
|
||||||
// var test = document.createElement("li");
|
|
||||||
// $(test)
|
|
||||||
// .addClass('list-group-item')
|
|
||||||
// .addClass('well')
|
|
||||||
// .addClass('well-sm')
|
|
||||||
// .attr({"data-input": functionCall, "data-output": output})
|
|
||||||
// .html(createTestString(functionCall, output))
|
|
||||||
// .appendTo($('#testSuite'));
|
|
||||||
// var closeLink = document.createElement('i');
|
|
||||||
// var closeSpan = document.createElement('span');
|
|
||||||
// $(closeSpan)
|
|
||||||
// .addClass("glyphicon glyphicon-remove-sign")
|
|
||||||
// //.css("float", "right")
|
|
||||||
// .click(function () {
|
|
||||||
// //var input = prompt("This will remove the test permanently.\n If you want to do this, type delete");
|
|
||||||
// if (/delete/.test(input.toLowerCase())) {
|
|
||||||
// $(this).parent().remove();
|
|
||||||
// }
|
|
||||||
// }).appendTo($(test));
|
|
||||||
// //blank out the form
|
|
||||||
// $("#testCreateForm").find("input[type=text]").val("");
|
|
||||||
//});
|
|
||||||
//var createTestString = function (inputs, output) {
|
|
||||||
// return "Input: " + inputs + "\nExpect:" + output;
|
|
||||||
//};
|
|
||||||
//var testOutput = CodeMirror.fromTextArea(document.getElementById("testOutput"), {
|
|
||||||
// lineNumbers: false,
|
|
||||||
// mode: "javascript",
|
|
||||||
// theme: 'monokai',
|
|
||||||
// readOnly: 'nocursor'
|
|
||||||
//});
|
|
||||||
//testOutput.setSize("100%", 200);
|
|
||||||
//var createOptions = function (re, code) {
|
|
||||||
// var m = re.exec(code);
|
|
||||||
// while (m != null) {
|
|
||||||
// var functionName = m[1];
|
|
||||||
// if (functionName !== undefined) {
|
|
||||||
// var option = document.createElement('option');
|
|
||||||
// $(option)
|
|
||||||
// .html(functionName)
|
|
||||||
// .attr({"data-args": m[2]})
|
|
||||||
// .appendTo($('#testFunctionName'));
|
|
||||||
// }
|
|
||||||
// m = re.exec(code);
|
|
||||||
// }
|
|
||||||
//};
|
|
||||||
// $('#testFunctionName').on('change', function () {
|
|
||||||
// $('#testInputs').children().remove();
|
|
||||||
// $('#testOutputs').children().remove();
|
|
||||||
// var args = $('#testFunctionName option:selected').data("args");
|
|
||||||
// var argArray = args.split(",");
|
|
||||||
// argArray.forEach(function (arg) {
|
|
||||||
// if (arg.length > 0) {
|
|
||||||
// createInputField('#testInputs', arg);
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// createInputField('#testOutputs', 'Expected output');
|
|
||||||
// });
|
|
||||||
// var createInputField = function (className, arg) {
|
|
||||||
// var inputDiv = document.createElement('div');
|
|
||||||
// $(inputDiv)
|
|
||||||
// .addClass("control-group")
|
|
||||||
// .appendTo($(className));
|
|
||||||
// var inputLabel = document.createElement('label');
|
|
||||||
// $(inputLabel)
|
|
||||||
// .attr("for", "inputs")
|
|
||||||
// .html(arg)
|
|
||||||
// .addClass("col-xs-4 control-label")
|
|
||||||
// .appendTo($(inputDiv));
|
|
||||||
// var textDiv = document.createElement('div');
|
|
||||||
// $(textDiv)
|
|
||||||
// .addClass("col-xs-8 controls")
|
|
||||||
// .appendTo($(inputDiv));
|
|
||||||
// var inputArea = document.createElement('input');
|
|
||||||
// $(inputArea)
|
|
||||||
// .attr("type", "text")
|
|
||||||
// .addClass("form-control")
|
|
||||||
// .appendTo($(inputDiv));
|
|
||||||
// $(document.createElement("br")).appendTo($(textDiv));
|
|
||||||
// };
|
|
||||||
// $('#testFunctionName').on('focus', function () {
|
|
||||||
// $('#testFunctionName').children().remove();
|
|
||||||
// var blankOpt = document.createElement("option");
|
|
||||||
// $(blankOpt).addClass("selected").appendTo($('#testFunctionName'));
|
|
||||||
// var re = /function\s+(\w+)\s*\(([\w\s,]*)\)/g;
|
|
||||||
// var code = myCodeMirror.getValue();
|
|
||||||
// createOptions(re, code);
|
|
||||||
// re = /var (\w+)\s*=\s*function\s*\(([\s\w,]*)\)/g;
|
|
||||||
// createOptions(re, code);
|
|
||||||
// });
|
|
||||||
// $('#hideTestCreate').on('click', function () {
|
|
||||||
// var testForm = $("#testCreateForm");
|
|
||||||
// if (testForm.is(":visible")) {
|
|
||||||
// testForm.hide();
|
|
||||||
// $(this).text("Create more tests");
|
|
||||||
// } else {
|
|
||||||
// testForm.show();
|
|
||||||
// $(this).text("Hide test creation dialogue")
|
|
||||||
// }
|
|
||||||
// });
|
|
60
seed_data/bonfires.json
Normal file
60
seed_data/bonfires.json
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "Palindrome Tester",
|
||||||
|
"difficulty": 1,
|
||||||
|
"description": [
|
||||||
|
"Your job is to determine if a provided string is a palindrome.",
|
||||||
|
"The definition of a palindrome can be found at http://en.wikipedia.org/wiki/Palindrome.",
|
||||||
|
"Strings will be passed in with varying formats, such as \"racecar\", \"RaceCar\", and \"race CAR\" among others.",
|
||||||
|
"Return true if the string is a palindrome, otherwise false"
|
||||||
|
],
|
||||||
|
"publicTests": [
|
||||||
|
"expect(palindrome(\"eye\")).to.be.a(\"boolean\");",
|
||||||
|
"assert.deepEqual(palindrome(\"eye\"), true);",
|
||||||
|
"assert.deepEqual(palindrome(\"race car\"), true);",
|
||||||
|
"assert.deepEqual(palindrome(\"not a palindrome\"), false);"
|
||||||
|
],
|
||||||
|
"privateTests": [
|
||||||
|
"assert.deepEqual(palindrome(\"A man, a plan, a canal. Panama\"), true);",
|
||||||
|
"assert.deepEqual(palindrome(\"never odd or even\"), true);",
|
||||||
|
"assert.deepEqual(palindrome(\"nope\"), false);"
|
||||||
|
],
|
||||||
|
"challengeSeed": "function palindrome(str) {\n // Good luck!\n return true;\n}\n\n",
|
||||||
|
"challengeEntryPoint": "palindrome(\"eye\");",
|
||||||
|
"bonfireNumber": 1,
|
||||||
|
"challengeEntryPointNegate" : "palindrome\\([^str].*\\;"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Validate US Telephone Numbers",
|
||||||
|
"difficulty": 3,
|
||||||
|
"description": [
|
||||||
|
"The user may fill out the form field any way they choose as long as it is a valid US number. The following are all valid formats for US numbers:",
|
||||||
|
"555-555-5555, (555)555-5555, (555) 555-5555, 555 555 5555, 5555555555, 1 555 555 5555",
|
||||||
|
"For this challenge you will be presented with a string such as \"800-692-7753\" or \"8oo-six427676;laskdjf\". Your job is to validate or reject the US phone number based on any combination of the formats provided above. The area code is required. If the country code code is provided, you must confirm that the country code is \"1\". Return true if the string is a valid US phone number; otherwise false."
|
||||||
|
],
|
||||||
|
"publicTests": [
|
||||||
|
"expect(telephoneCheck(\"555-555-5555\")).to.be.a(\"boolean\");",
|
||||||
|
"assert.deepEqual(telephoneCheck(\"555-555-5555\"), true);",
|
||||||
|
"assert.deepEqual(telephoneCheck(\"1 456 789 4444\"), true);",
|
||||||
|
"assert.deepEqual(telephoneCheck(\"123**&!!asdf#\"), false);"
|
||||||
|
],
|
||||||
|
"privateTests": [
|
||||||
|
"assert.deepEqual(telephoneCheck(\"55555555\"), false);",
|
||||||
|
"assert.deepEqual(telephoneCheck(\"(6505552368)\"), false);",
|
||||||
|
"assert.deepEqual(telephoneCheck(\"2 (757) 622-7382\"), false);",
|
||||||
|
"assert.deepEqual(telephoneCheck(\"0 (757) 622-7382\"), false);",
|
||||||
|
"assert.deepEqual(telephoneCheck(\"-1 (757) 622-7382\"), false);",
|
||||||
|
"assert.deepEqual(telephoneCheck(\"2 757 622-7382\"), false);",
|
||||||
|
"assert.deepEqual(telephoneCheck(\"10 (757) 622-7382\"), false);",
|
||||||
|
"assert.deepEqual(telephoneCheck(\"27576227382\"), false);",
|
||||||
|
"assert.deepEqual(telephoneCheck(\"(275)76227382\"), false);",
|
||||||
|
"assert.deepEqual(telephoneCheck(\"2(757)6227382\"), false);",
|
||||||
|
"assert.deepEqual(telephoneCheck(\"2(757)622-7382\"), false);"
|
||||||
|
],
|
||||||
|
"challengeSeed": "function telephoneCheck(str) {\n // Good luck!\n return true;\n}\n\n",
|
||||||
|
"challengeEntryPoint": "telephoneCheck(\"555-555-5555\");",
|
||||||
|
"bonfireNumber": 2,
|
||||||
|
"challengeEntryPointNegate" : "palindrome\\([^str].*\\;"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
202
seed_data/challenge-hashes
Normal file
202
seed_data/challenge-hashes
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
/*
|
||||||
|
"aaa48de84e1ecc7c742e1124"
|
||||||
|
"ff0395860f5d3034dc0bfc94"
|
||||||
|
"7123c8c441eddfaeb5bdef0d"
|
||||||
|
"c3a4d278b9e760a0ffe8321f"
|
||||||
|
"aceca143b92049a4392a859e"
|
||||||
|
"ce9394f67d413734758e27e4"
|
||||||
|
"1369953ef6f03098cb60e2f7"
|
||||||
|
"fa229986db0716662e63163a"
|
||||||
|
"0a6207dfc9ac12f223b4e686"
|
||||||
|
"2e538b339cbcb7437e61d71f"
|
||||||
|
"21de1104b8ea7c6a382442d9"
|
||||||
|
"0aa3497514cb1d8a0ed04933"
|
||||||
|
"3a45068415f5a20a5d4a2039"
|
||||||
|
"6a73ec9b86f0e742f6c6ea76"
|
||||||
|
"06dc21940748badcdb29561e"
|
||||||
|
"0f2341ef36740b5c2b9d830c"
|
||||||
|
"dc4cc7ce1fd0418859b10e0b"
|
||||||
|
"1fcda9b5e0bf502c8b770374"
|
||||||
|
"482879c42188cde1f9ad3d8f"
|
||||||
|
"3d680bd03fd291028af57f4f"
|
||||||
|
"6b444fe5aa97359238bd3c0d"
|
||||||
|
"72d6ad274e72ffcd399e05cb"
|
||||||
|
"e864a710647bb6883c9ec617"
|
||||||
|
"024dcd8cc0178de7daa4f59f"
|
||||||
|
"ded24fb937a3fd60dc624677"
|
||||||
|
"9ad4c3b2aebe7282e973e5df"
|
||||||
|
"d16c66ecc656c82899a2d427"
|
||||||
|
"ee3e4bf39b840609dd88f5af"
|
||||||
|
"9a10d27eb6ab6f5030bdbcd9"
|
||||||
|
"b4cca5ecdeca1eebc0dc4183"
|
||||||
|
"ccdf1ef407864df62b03331e"
|
||||||
|
"1baa0329f02e41a5517b11a6"
|
||||||
|
"b5b33e5ecf6c02a5780ac419"
|
||||||
|
"84b690f53cd6cbbbf4a361f5"
|
||||||
|
"4e3b1b9d41ff11bdf3722ffe"
|
||||||
|
"1fd45e64c43cd640abcf8a76"
|
||||||
|
"c8bd32cdd943c88fb8a74934"
|
||||||
|
"9e5440269d09b71f07002333"
|
||||||
|
"5080016b8b68f40f7476c341"
|
||||||
|
"f762d45cc870d9f18c6b7024"
|
||||||
|
"cf21358ab1245c7033504b42"
|
||||||
|
"41eff7cb0f2fd8ec9e0cbf68"
|
||||||
|
"a344c63de6a00feea5c541e0"
|
||||||
|
"7ab3c18c0815d7b1f02e8768"
|
||||||
|
"a6f36e4387e2e1e25af4e000"
|
||||||
|
"9064af1431c1ff3aaa15a0d6"
|
||||||
|
"50946066aaba43a294155ab5"
|
||||||
|
"70e82e77857317d6936ecdcc"
|
||||||
|
"dc644dc20d5b02ffd7c8cc94"
|
||||||
|
"92af1e9f1813619d820dec4d"
|
||||||
|
"9d4a077fdaaa24b78a54cee9"
|
||||||
|
"cfd5fa7aea14fb294bd4f5ff"
|
||||||
|
"068541b6c5130ca541d6c05c"
|
||||||
|
"39f4d1f12142d583b0318265"
|
||||||
|
"4a201b8fa69d11cb669dca8c"
|
||||||
|
"6fa6bba2e334dd2c9e5a6911"
|
||||||
|
"30ff082b6a28558f16743fea"
|
||||||
|
"afed31c4dc2ddf056e263acb"
|
||||||
|
"b2431ecf36f0b780959aa03d"
|
||||||
|
"54e42938ab6fa923a5fbfbff"
|
||||||
|
"48d50e3ff5e96f152d912ebf"
|
||||||
|
"6c7aad2ee996132f76630c05"
|
||||||
|
"2705f0482774977fa9b5c7bc"
|
||||||
|
"c09d6682c7a144d9afd4bfab"
|
||||||
|
"1a0a30c55dd9bc2fff4e2aac"
|
||||||
|
"30c22b502e80afd144d79120"
|
||||||
|
"8f882989bbc98c68b6c7347e"
|
||||||
|
"888bf771b63a5f64e6b696ed"
|
||||||
|
"959aa13a2e6439fd5d29c5fe"
|
||||||
|
"d03d311ca64bf59a2404dcd0"
|
||||||
|
"7a650f3e4308a097d7883b1f"
|
||||||
|
"54c207808ac349fa34ed24a9"
|
||||||
|
"3cb12e3ea31fe15ba9d234e5"
|
||||||
|
"0d9f8123e52f791ae172f627"
|
||||||
|
"387518b1bb96bd918e7d0b91"
|
||||||
|
"27198d8918c9802ac0b06a58"
|
||||||
|
"7a519a552f723c6b1fdc9389"
|
||||||
|
"4240096651a50f888765ed60"
|
||||||
|
"8ba94f78cc44cfb82b3678d2"
|
||||||
|
"1cf7c3bda6ec7952923bc90f"
|
||||||
|
"cd54811e976edbc798a87c24"
|
||||||
|
"e4ee17912f5d7d80d41dc52d"
|
||||||
|
"572346dd1874a0c749c3a031"
|
||||||
|
"cf700031502680580ff25980"
|
||||||
|
"7054518832e5c7efde04a58c"
|
||||||
|
"7716c6b6a3dcc9c5df79a262"
|
||||||
|
"f4d1084c692f5a07c25a1b47"
|
||||||
|
"817b80892a78fc6f83eab4eb"
|
||||||
|
"ae0e0adda6d063d3fd2c9499"
|
||||||
|
"33184c427ecaab77b5332521"
|
||||||
|
"c6c4da707e3eed987eb65ba6"
|
||||||
|
"40f9801913c0cb9800960bf7"
|
||||||
|
"af11cf78e8340f172ba76bbe"
|
||||||
|
"c1daea28b5996b8e8800e300"
|
||||||
|
"7312b3234b5f2f50887597b9"
|
||||||
|
"3e4361c5356b30f8ce833268"
|
||||||
|
"e6fc8827b9aa96fc91035ac2"
|
||||||
|
"11658fe51b23319533c72106"
|
||||||
|
"34207fe236870fd855392ef6"
|
||||||
|
"dc970a2b17aa1432d180d078"
|
||||||
|
"2f1686ad711b5ac3d98905b5"
|
||||||
|
"ed20f4bf782e10ec26c7b3b1"
|
||||||
|
"cf4d6241df36b0bbcea401e2"
|
||||||
|
"97e414eb00338bd7bd5d1b31"
|
||||||
|
"bcfebb743729d4fc51b0db49"
|
||||||
|
"52782c1eaa15e050ac748b18"
|
||||||
|
"57f65a6cd2eb0a2745fc90ee"
|
||||||
|
"fcc569e80808c6cd84c839cc"
|
||||||
|
"2447f8e0e3ccfd895a619695"
|
||||||
|
"600687fe6332b2e2b20d6a84"
|
||||||
|
"0f8a972361baddb3ac64b6d9"
|
||||||
|
"f768594ab352cf8e2282b615"
|
||||||
|
"3163b25e25b0d6859df17751"
|
||||||
|
"c73d68f0cf77aa113337fcde"
|
||||||
|
"cc16163137f13f70decbcb5c"
|
||||||
|
"4adbf6c7ac2004ee8ae20f55"
|
||||||
|
"c2779f78a0e57dcee471cefd"
|
||||||
|
"bf44903cd2fca4ae4daf0818"
|
||||||
|
"ca8013372d58365e21bd0428"
|
||||||
|
"e308901ca272ad447dca965a"
|
||||||
|
"ec8cefe29832cd726185119f"
|
||||||
|
"36bf51da3f32b1e9550f3b15"
|
||||||
|
"aefff6dffdf534a6c9601f70"
|
||||||
|
"ce237971a71127f9ce747232"
|
||||||
|
"99f4d97fae16ccbeb8c26d46"
|
||||||
|
"c9f6480328ec4b63b1034826"
|
||||||
|
"ce10bb6e80b09533cb21c9a5"
|
||||||
|
"311a54aaf062b29422ac0b02"
|
||||||
|
"b2073bec873b295c04e9fb7e"
|
||||||
|
"7b7d94035d63c9c0598b242b"
|
||||||
|
"e19e9a0487f1bd3eabdb777c"
|
||||||
|
"eeafe5169a2afd9ce3979698"
|
||||||
|
"96c7a1f9fb73468fdb770034"
|
||||||
|
"77e607be2498160d3ceeff60"
|
||||||
|
"c784fa6b1fd7d9aedb05b607"
|
||||||
|
"a76319bca87e0b57bc79064f"
|
||||||
|
"a08db36785c51e5b92a6e92f"
|
||||||
|
"0933ab4a366d57fd1f1c0a48"
|
||||||
|
"17663f17a835cfe0bca64f4a"
|
||||||
|
"aee8323d1de634fc42c11d90"
|
||||||
|
"682044caf09a068e26c11cab"
|
||||||
|
"1346fdbe3c6fcb808b99cdf6"
|
||||||
|
"26fd8f47fe4791e2dd07b2e0"
|
||||||
|
"b1da27dd129216c2ead2e162"
|
||||||
|
"618adebe192e896eb1501708"
|
||||||
|
"2628d9eeb38db68c0b255a75"
|
||||||
|
"1fb78eda5deb8972cc357a9b"
|
||||||
|
"2fdebb85a401de75bb580a02"
|
||||||
|
"c59eae24bee36f63c938723d"
|
||||||
|
"fb66b55d5617e27ca64836a3"
|
||||||
|
"55994022872e01fd41d8ec7b"
|
||||||
|
"53ae83b5490e1cf55625ff3d"
|
||||||
|
"c44975deeb67b96e6cc37eb5"
|
||||||
|
"94c64d5ff48ca6487f5e0b07"
|
||||||
|
"e34e7c1a3d70678955a5df8e"
|
||||||
|
"6426d30a923dec6377132c47"
|
||||||
|
"d67811849354ded9d34c9ece"
|
||||||
|
"01e7ae81207cfd230cb02747"
|
||||||
|
"e24558477f94bcdd82f16ebe"
|
||||||
|
"4370f6dcc2f53bd5abed7899"
|
||||||
|
"679b1145cd3072fbcd513bcb"
|
||||||
|
"4dafd3fd84e7a337ef3e9933"
|
||||||
|
"2aca3d41cb148603b4a2d70b"
|
||||||
|
"5e5aa8c960d024109543c577"
|
||||||
|
"c5f5f313c8a7056bbcdb7639"
|
||||||
|
"a7b2aaa4cf85fce98cdeb314"
|
||||||
|
"e556c0d14bc0ce9cc7bde0ca"
|
||||||
|
"922a8284880a7c879d846f90"
|
||||||
|
"b146cf2fbf206ca48687e9b6"
|
||||||
|
"fbdc52bb7c7620bd4508e5a3"
|
||||||
|
"23d79a262a81459e75576cc2"
|
||||||
|
"a26721706d3b9f971cef3ce6"
|
||||||
|
"fb3801ed1b056a3ab4bbfdc1"
|
||||||
|
"d5cafae617f1485826de335c"
|
||||||
|
"e9650dfc8b570f9d33381012"
|
||||||
|
"453c804c7ce82e83305cd751"
|
||||||
|
"3eaab01bdd1393be8d461777"
|
||||||
|
"2b6d9ddd4754b71d92ed31b7"
|
||||||
|
"2338e9af6acab9fcf5327f6a"
|
||||||
|
"588e7405c30c346ed2ea5e44"
|
||||||
|
"eec8837994054fb2043b6166"
|
||||||
|
"0877406795956ca9eb13fea1"
|
||||||
|
"1dea30e852067eec48a24035"
|
||||||
|
"ee716ce45ea812167ed2497a"
|
||||||
|
"9621d5aeaf8de9b2f58977bd"
|
||||||
|
"e9bb838723083bac7f83d602"
|
||||||
|
"ef64da08bbe787891d47c31b"
|
||||||
|
"e01b6616cc6cf7819172f7f3"
|
||||||
|
"17c821c34fca587daec981fc"
|
||||||
|
"d0c4b7153dcb3e6af47bcd98"
|
||||||
|
"5188eb00680051c35cd6e0f0"
|
||||||
|
"9fc7b68e736a1f4931226ad8"
|
||||||
|
"b5eac897471f125224a3e594"
|
||||||
|
"c1d0f890a02c85a9320f96d5"
|
||||||
|
"7e3b1ca1b1b1e990367f0cc2"
|
||||||
|
"bff5ff77174c43f7c681e0bd"
|
||||||
|
"ddeb794121937d07a887c9e6"
|
||||||
|
"9db902e930f25fbacc125087"
|
||||||
|
"4f82d277b47ae9c98095f068"
|
||||||
|
"24f999491fa46cd194c7fd35"
|
||||||
|
*/
|
59
seed_data/seed.js
Normal file
59
seed_data/seed.js
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
require('dotenv').load();
|
||||||
|
var Challenge = require('../models/Challenge.js'),
|
||||||
|
Bonfire = require('../models/Bonfire.js'),
|
||||||
|
mongoose = require('mongoose'),
|
||||||
|
secrets = require('../config/secrets'),
|
||||||
|
challenges = require('./challenges.json'),
|
||||||
|
bonfires = require('./bonfires.json');
|
||||||
|
|
||||||
|
mongoose.connect(secrets.db);
|
||||||
|
|
||||||
|
var counter = 0;
|
||||||
|
|
||||||
|
var CompletionMonitor = function() {
|
||||||
|
counter++;
|
||||||
|
console.log('call ' + counter);
|
||||||
|
|
||||||
|
if (counter < 2) {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Challenge.remove({}, function(err, data) {
|
||||||
|
if (err) {
|
||||||
|
console.error(err);
|
||||||
|
} else {
|
||||||
|
console.log('Deleted ', data);
|
||||||
|
}
|
||||||
|
Challenge.create(challenges, function(err, data) {
|
||||||
|
if (err) {
|
||||||
|
console.log(err);
|
||||||
|
} else {
|
||||||
|
console.log('Saved ', data);
|
||||||
|
}
|
||||||
|
CompletionMonitor();
|
||||||
|
});
|
||||||
|
console.log('challenges');
|
||||||
|
});
|
||||||
|
|
||||||
|
Bonfire.remove({}, function(err, data) {
|
||||||
|
if (err) {
|
||||||
|
console.error(err);
|
||||||
|
} else {
|
||||||
|
console.log('Deleted ', data);
|
||||||
|
}
|
||||||
|
Bonfire.create(bonfires, function(err, data) {
|
||||||
|
if (err) {
|
||||||
|
console.log(err);
|
||||||
|
} else {
|
||||||
|
console.log('Saved ', data);
|
||||||
|
}
|
||||||
|
CompletionMonitor();
|
||||||
|
});
|
||||||
|
console.log('bonfires');
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
|||||||
require('dotenv').load();
|
|
||||||
var Challenge = require('../models/Challenge.js'),
|
|
||||||
mongoose = require('mongoose'),
|
|
||||||
secrets = require('../config/secrets'),
|
|
||||||
challenges = require('./challenges.json');
|
|
||||||
|
|
||||||
mongoose.connect(secrets.db);
|
|
||||||
|
|
||||||
Challenge.remove({}, function(err, data) {
|
|
||||||
if (err) {
|
|
||||||
console.error(err);
|
|
||||||
} else {
|
|
||||||
console.log('Deleted ', data);
|
|
||||||
}
|
|
||||||
Challenge.create(challenges, function(err, data) {
|
|
||||||
if (err) {
|
|
||||||
console.log(err);
|
|
||||||
} else {
|
|
||||||
console.log('Saved ', data);
|
|
||||||
}
|
|
||||||
process.exit(0);
|
|
||||||
});
|
|
||||||
});
|
|
@ -12,8 +12,8 @@ block content
|
|||||||
link(rel='stylesheet', href='/js/lib/codemirror/theme/monokai.css')
|
link(rel='stylesheet', href='/js/lib/codemirror/theme/monokai.css')
|
||||||
link(rel="stylesheet", href="http://fonts.googleapis.com/css?family=Ubuntu+Mono")
|
link(rel="stylesheet", href="http://fonts.googleapis.com/css?family=Ubuntu+Mono")
|
||||||
script(src='/js/lib/codemirror/mode/javascript/javascript.js')
|
script(src='/js/lib/codemirror/mode/javascript/javascript.js')
|
||||||
script(src='js/lib/jailed/jailed.js')
|
script(src='/js/lib/jailed/jailed.js')
|
||||||
script(src='/js/lib/bonfire/bonfire.js')
|
script(src='/js/lib/bonfire/bonfireInit.js')
|
||||||
.row
|
.row
|
||||||
#mainEditorPanel.col-sm-12.col-md-7.col-xs-12
|
#mainEditorPanel.col-sm-12.col-md-7.col-xs-12
|
||||||
.panel.panel-primary.panel-bonfire
|
.panel.panel-primary.panel-bonfire
|
||||||
@ -36,4 +36,4 @@ block content
|
|||||||
br
|
br
|
||||||
ul#testSuite.list-group
|
ul#testSuite.list-group
|
||||||
br
|
br
|
||||||
script(src='/js/lib/bonfire/framework.js')
|
script(src='/js/lib/bonfire/bonfireFramework.js')
|
50
views/bonfire/show.jade
Normal file
50
views/bonfire/show.jade
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
extends ../layout
|
||||||
|
block content
|
||||||
|
|
||||||
|
script(src='/js/lib/codemirror/lib/codemirror.js')
|
||||||
|
script(src='/js/lib/codemirror/addon/edit/closebrackets.js')
|
||||||
|
script(src='/js/lib/codemirror/addon/edit/matchbrackets.js')
|
||||||
|
script(src='/js/lib/codemirror/addon/lint/lint.js')
|
||||||
|
script(src='/js/lib/codemirror/addon/lint/javascript-lint.js')
|
||||||
|
script(src='//ajax.aspnetcdn.com/ajax/jshint/r07/jshint.js')
|
||||||
|
script(src='/js/lib/chai/chai.js')
|
||||||
|
link(rel='stylesheet', href='/js/lib/codemirror/lib/codemirror.css')
|
||||||
|
link(rel='stylesheet', href='/js/lib/codemirror/addon/lint/lint.css')
|
||||||
|
link(rel='stylesheet', href='/js/lib/codemirror/theme/monokai.css')
|
||||||
|
link(rel="stylesheet", href="http://fonts.googleapis.com/css?family=Ubuntu+Mono")
|
||||||
|
script(src='/js/lib/codemirror/mode/javascript/javascript.js')
|
||||||
|
script(src='/js/lib/jailed/jailed.js')
|
||||||
|
script(src='/js/lib/bonfire/bonfireInit.js')
|
||||||
|
|
||||||
|
|
||||||
|
.row
|
||||||
|
#mainEditorPanel.col-sm-12.col-md-7.col-xs-12
|
||||||
|
.panel.panel-primary.panel-bonfire
|
||||||
|
.panel-heading.text-center #{name} (Level #{difficulty} bonfire)
|
||||||
|
.panel.panel-body
|
||||||
|
.well
|
||||||
|
.text-justify.bonfire-instructions
|
||||||
|
for sentence in description
|
||||||
|
p.bonfire-instructions!= sentence
|
||||||
|
form.code
|
||||||
|
.form-group.codeMirrorView
|
||||||
|
textarea#codeEditor(autofocus=true)
|
||||||
|
#testCreatePanel.col-sm-12.col-md-5.col-xs-12
|
||||||
|
.panel.panel-primary.panel-bonfire
|
||||||
|
.panel-heading.text-center Output
|
||||||
|
.panel.panel-body
|
||||||
|
#submitButton.btn.btn-primary.btn-big.btn-block Run code (ctrl + enter)
|
||||||
|
br
|
||||||
|
form.code
|
||||||
|
.form-group.codeMirrorView
|
||||||
|
textarea#codeOutput
|
||||||
|
br
|
||||||
|
ul#testSuite.list-group
|
||||||
|
br
|
||||||
|
script(type="text/javascript").
|
||||||
|
var publicTests = !{JSON.stringify(publicTests)};
|
||||||
|
var privateTests = !{JSON.stringify(privateTests)};
|
||||||
|
var challengeSeed = !{JSON.stringify(challengeSeed)};
|
||||||
|
var challengeEntryPoint = !{JSON.stringify(challengeEntryPoint)};
|
||||||
|
var challengeEntryPointNegate = !{JSON.stringify(challengeEntryPointNegate)};
|
||||||
|
script(src='/js/lib/bonfire/bonfireFramework.js')
|
@ -1,6 +1 @@
|
|||||||
h3
|
//TODO: STUFF
|
||||||
ol(start='0')
|
|
||||||
for bonfire in bonfires
|
|
||||||
li
|
|
||||||
a(href="/bonfire/#{bonfire.bonfireNumber}", class="#{ (cc && cc[bonfire.bonfireNumber] > 0) ? 'strikethrough' : '' }") #{bonfire.name}
|
|
||||||
| (#{bonfire.time} mins)
|
|
Reference in New Issue
Block a user