generator now publishes directly to a view where you can interact with your new bonfire

This commit is contained in:
Michael Q Larson
2015-01-25 23:10:05 -08:00
parent 7c6cbbf221
commit c20aa1697c
7 changed files with 170 additions and 92 deletions

2
app.js
View File

@ -263,6 +263,8 @@ app.get(
app.get('/bonfires', bonfireController.returnBonfire);
app.get('/bonfire/generator', bonfireController.returnGenerator);
app.post('/bonfire/generator', bonfireController.generateChallenge);
app.get('/bonfire/public-generator', bonfireController.publicGenerator);
app.post('/bonfire/public-generator', bonfireController.testBonfire)
// Unique Check API route
app.get('/api/checkUniqueUsername/:username', userController.checkUniqueUsername);

View File

@ -15,7 +15,7 @@ exports.index = function(req, res) {
title: 'Learn to code with Bonfire'
});
Bonfire.find({}, null, { sort: { bonfireNumber: 1 } }, function(err, c) {
Bonfire.find({}, null, { sort: { difficulty: 1 } }, function(err, c) {
if (err) {
debug('bonfire err: ', err);
next(err);
@ -49,8 +49,7 @@ exports.returnBonfire = function(req, res, next) {
completedWith: null,
title: bonfire[bonfireNumber].name,
name: bonfire[bonfireNumber].name,
number: bonfire[bonfireNumber].bonfireNumber,
difficulty: bonfire[bonfireNumber].difficulty,
difficulty: +bonfire[bonfireNumber].difficulty,
brief: bonfire[bonfireNumber].description[0],
details: bonfire[bonfireNumber].description.slice(1),
tests: bonfire[bonfireNumber].tests,
@ -71,7 +70,7 @@ exports.returnIndividualBonfire = function(req, res, next) {
var bonfireNumber = parseInt(req.params.bonfireNumber) || 0;
if (bonfireNumber > highestBonfireNumber) { bonfireNumber = 0; }
Bonfire.find({}, null, { sort: { bonfireNumber: 1 } }, function(err, bonfire) {
Bonfire.find({}, null, { sort: { difficulty: 1 } }, function(err, bonfire) {
if (err) {
next(err);
}
@ -79,8 +78,7 @@ exports.returnIndividualBonfire = function(req, res, next) {
completedWith: null,
title: bonfire[bonfireNumber].name,
name: bonfire[bonfireNumber].name,
number: bonfire[bonfireNumber].bonfireNumber,
difficulty: bonfire[bonfireNumber].difficulty,
difficulty: +bonfire[bonfireNumber].difficulty,
brief: bonfire[bonfireNumber].description[0],
details: bonfire[bonfireNumber].description.slice(1),
tests: bonfire[bonfireNumber].tests,
@ -134,25 +132,33 @@ function randomString() {
*/
exports.testBonfire = function(req, res) {
// TODO: Add stuff here to parse posted variables and feed them back to bonfire playground
var candidateTitle = req.body.bonfireInfo.title;
var candidateName = req.body.bonfireInfo.name;
var candidateDifficulty = req.body.bonfireInfo.difficulty;
var candidateBrief = req.body.bonfireInfo.brief;
var candidateDetails = req.body.bonfireInfo.details;
var candidateTests = req.body.bonfireInfo.tests;
var candidateChallengeSeed = req.body.bonfireInfo.challengeSeed;
var candidateChallengeEntryPoint = req.body.bonfireInfo.challengeSeed;
res.render('bonfire/bonfire', {
title: candidateTitle,
name: candidateName,
difficulty: candidateDifficulty,
brief: candidateBrief,
details: candidateDetails,
tests: candidateTests,
challengeSeed: candidateChallengeSeed,
challengeEntryPoint: candidateChallengeEntryPoint,
bonfireHash: bonfire[bonfireNumber]._id
var bonfireName = req.body.name,
bonfireTests = req.body.tests,
bonfireDifficulty = req.body.difficulty,
bonfireDescription = req.body.description,
bonfireEntryPoint = req.body.challengeEntryPoint,
bonfireChallengeSeed = req.body.challengeSeed;
bonfireTests = bonfireTests.split('\r\n');
bonfireDescription = bonfireDescription.split('\r\n');
bonfireTests.filter(getRidOfEmpties);
bonfireDescription.filter(getRidOfEmpties);
bonfireChallengeSeed = bonfireChallengeSeed.replace('\r', '');
res.render('bonfire/show', {
completedWith: null,
title: bonfireName,
difficulty: +bonfireDifficulty,
brief: bonfireDescription[0],
details: bonfireDescription.slice(1),
tests: bonfireTests,
challengeSeed: bonfireChallengeSeed,
challengeEntryPoint: bonfireEntryPoint,
cc: req.user ? req.user.bonfiresHash : undefined,
points: req.user ? req.user.points : undefined,
verb: resources.randomVerb(),
phrase: resources.randomPhrase(),
compliment: resources.randomCompliment(),
bonfires: [],
bonfireHash: "test"
});
};
@ -162,6 +168,10 @@ function getRidOfEmpties(elem) {
}
}
exports.publicGenerator = function(req, res) {
res.render('bonfire/public-generator');
}
exports.generateChallenge = function(req, res) {
var bonfireName = req.body.name,
bonfireTests = req.body.tests,
@ -177,14 +187,13 @@ exports.generateChallenge = function(req, res) {
var response = {
_id: randomString(),
name: bonfireName,
tests: bonfireTests,
difficulty: bonfireDifficulty,
description: bonfireDescription,
challengeEntryPoint: bonfireEntryPoint,
challengeSeed: bonfireChallengeSeed,
bonfireNumber: 0,
_id: randomString()
tests: bonfireTests
};
res.send(response);
}

View File

@ -12,14 +12,12 @@ var bonfireSchema = new mongoose.Schema({
type: String,
unique: true
},
difficulty: Number,
difficulty: String,
description: Array,
tests: Array,
challengeSeed: String,
bonfireNumber: Number,
challengeEntryPoint: String,
challengeEntryPointNegate: String
});
module.exports = mongoose.model('Bonfire', bonfireSchema);

View File

@ -216,7 +216,8 @@ var runTests = function(err, data) {
userTests.forEach(function(test, ix, arr){
try {
if (test) {
var output = eval(reassembleTest(test, data));
var test = JSON.stringify(reassembleTest(test, data));
var output = eval(test);
}
} catch(error) {
allTestsPassed = false;

View File

@ -2,7 +2,7 @@
{
"_id" : "7123c8c441eddfaeb5bdef0d",
"name": "Meet Bonfire",
"difficulty": 1,
"difficulty": "0",
"description": [
"Click the button below for further instructions.",
"Your goal is to fix the failing test.",
@ -15,12 +15,11 @@
],
"challengeSeed": "function meetBonfire(argument) {\n // Good luck!\n console.log(\"you can read this function's argument in the developer tools\", argument);\n\nreturn false;\n}\n\n",
"challengeEntryPoint": "meetBonfire(\"You can do this!\");",
"bonfireNumber": 0
},
{
"_id" : "aaa48de84e1ecc7c742e1124",
"name": "Check for Palindromes",
"difficulty": 1,
"difficulty": "1",
"description": [
"Return 'true' if a given string is a palindrome.",
"A palindrome is a word or sentence that's spelled the same way both forward and backward, ignoring punctuation and case.",
@ -39,12 +38,11 @@
],
"challengeSeed": "function palindrome(str) {\n // Good luck!\n return true;\n}\n\n",
"challengeEntryPoint": "palindrome(\"eye\");",
"bonfireNumber": 1
},
{
"_id" : "ff0395860f5d3034dc0bfc94",
"name": "Validate US Telephone Numbers",
"difficulty": 3,
"difficulty": "3",
"description": [
"Return true if the passed string is a valid US phone number",
"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:",
@ -77,76 +75,96 @@
],
"challengeSeed": "function telephoneCheck(str) {\n // Good luck!\n return true;\n}\n\n",
"challengeEntryPoint": "telephoneCheck(\"555-555-5555\");",
"bonfireNumber": 2
},
{
"_id": "202eed8fc186c8434cb6d618",
"name": "Reverse a String",
"difficulty": "1",
"tests": [
"expect(reverseString('hello')).to.be.a('String');",
"expect(reverseString('hello')).to.equal('olleh');",
"expect(reverseString('Howdy')).to.equal('ydwoH');",
"expect(reverseString('Greetings from Earth')).to.equal('htraE morf sgniteerG');"
],
"difficulty": "1",
"description": [
"Reverse the provided string. ",
"Reverse the provided string.",
"You may need to turn the string into an array before you can reverse it.",
"Your result must be a string."
],
"challengeEntryPoint": "reverseString('hello');",
"challengeSeed": "function reverseString(str) {\n return str;\r\n}",
"bonfireNumber": 0,
"_id": "202eed8fc186c8434cb6d618"
},
{
"_id": "302f7aae1aa3152a5b413bca",
"name": "Factorialize a Number",
"tests": [
"expect(factorialize(5)).to.be.a(\"Number\");",
"expect(factorialize(5)).to.equal(120);",
"expect(factorialize(10)).to.equal(3628800);",
"expect(factorialize(20)).to.equal(2432902008176640000);"
],
"difficulty": "1",
"description": [
"Return the factorial of the provided integer.",
"If the integer is represented with the letter n, a factorial is the product of all positive integers less than or equal to n.",
"Factorials are often represented with the shorthand notation n!",
"For example: 5! = 1 * 2 * 3 * 4 * 5 = 120f"
],
"challengeSeed": "function factorialize(num) {\n return num;\r\n}",
"challengeEntryPoint": "factorialize(5);"
},
{
"_id": "a26cbbe9ad8655a977e1ceb5",
"name": "Find the Longest Word in a String",
"difficulty": "1",
"description": [
"Return the length of the longest word in the provided sentence.",
"Your response should be a number."
],
"challengeEntryPoint": "findLongestWord('The quick brown fox jumped over the lazy dog');",
"challengeSeed": "function findLongestWord(str) {\n return str.length;\r\n}",
"tests": [
"expect(findLongestWord('The quick brown fox jumped over the lazy dog')).to.be.a('Number');",
"expect(findLongestWord('The quick brown fox jumped over the lazy dog')).to.equal(6);",
"expect(findLongestWord('May the force be with you')).to.equal(5);",
"expect(findLongestWord('Google do a barrel roll')).to.equal(6);",
"expect(findLongestWord('What is the average airspeed velocity of an unladen swallow')).to.equal(8);"
]
},
{
"_id": "3566b1109230028080c9345d",
"name": "Sum All Numbers in a Range",
"difficulty": "2",
"description": [
"We'll pass you an array of two numbers. Return the sum those two numbers and all numbers between them.",
"The lowest number will not always come first."
],
"challengeEntryPoint": "sumAll([1, 4]);",
"challengeSeed": "function sumAll(arr) {\n return(1);\r\n}",
"tests": [
"expect(sumAll([1, 4])).to.be.a('Number');",
"expect(sumAll([1, 4])).to.equal(10);",
"expect(sumAll([4, 1])).to.equal(10);",
"expect(sumAll([5, 10])).to.equal(45);",
"expect(sumAll([10, 5])).to.equal(45);"
]
},
{
"_id": "fb6137d4e35944e21037b769",
"name": "Title Case a Sentence",
"difficulty": "1",
"description": [
"Return the provided string with the first letter of each word capitalized.",
"For the purpose of this exercise, you should also capitalize connecting words like 'the' and 'of'."
],
"challengeEntryPoint": "titleCase(\"I'm a little tea pot\")",
"challengeSeed": "function titleCase(str) {\n return str;\r\n}",
"tests": [
"expect(titleCase(\"I'm a little tea pot\")).to.be.a('String');",
"expect(titleCase(\"I'm a little tea pot\")).to.equal(\"I'm A Little Tea Pot\");",
"expect(titleCase(\"sHoRt AnD sToUt\")).to.equal(\"Short And Stout\");",
"expect(titleCase(\"HERE IS MY HANDLE HERE IS MY SPOUT\")).to.equal(\"Here Is My Handle Here Is My Spout\");"
]
}
]

View File

@ -15,6 +15,12 @@ block content
script(src='/js/lib/jailed/jailed.js')
script(src='/js/lib/bonfire/bonfireInit.js')
.row
script(type="text/javascript").
var tests = !{JSON.stringify(tests)};
var challengeSeed = !{JSON.stringify(challengeSeed)};
var challengeEntryPoint = !{JSON.stringify(challengeEntryPoint)};
var title = !{JSON.stringify(title)};
#mainEditorPanel.col-sm-12.col-md-7.col-xs-12
.panel.panel-primary.panel-bonfire
.panel-heading.text-center Playground

View File

@ -0,0 +1,44 @@
extends ../layout
block content
.row
.col-md-offset-2.col-md-8.col-lg-offset-2.col-lg-8.text-center
h1 JSON generator for bonfire challenges - just fill the form out and get the correct format back
.col-xs-12.col-sm-12.col-md-offset-3.col-md-6.col-lg-offset-3-col-lg-6
.panel
form.form-horizontal(method="POST", action="/bonfire/public-generator", name="bonfireInfo")
.form-group
label.col-sm-2.control-label(for='name') name:
.col-sm-10
input#name.form-control(type='text', placeholder='name', name="name")
.form-group
label.col-sm-2.control-label(for='difficultyField') difficulty:
.col-sm-10
label.radio-inline 1
input#inlineRadio1(type='radio', name='difficulty', value='1')
label.radio-inline 2
input#inlineRadio2(type='radio', name='difficulty', value='2')
label.radio-inline 3
input#inlineRadio3(type='radio', name='difficulty', value='3')
label.radio-inline 4
input#inlineRadio4(type='radio', name='difficulty', value='4')
label.radio-inline 5
input#inlineRadio5(type='radio', name='difficulty', value='5')
.form-group
label.col-sm-2.control-label.wrappable(for='description') description:
.col-sm-10
textarea#description.form-control(name="description", placeholder="Separate sentences by exactly one space only. Do not add in line breaks.")
.form-group
label.col-sm-2.control-label.wrappable(for='challengeSeed') challengeSeed:
.col-sm-10
textarea#challengeSeed.form-control(name="challengeSeed", rows=5)
.form-group
label.col-sm-2.control-label.wrappable(for='challengeEntryPoint') challenge entrypoint:
.col-sm-10
textarea#name.form-control(name="challengeEntryPoint", rows=1, type='text', placeholder="palindrome(\"eye\");")
.form-group
label.col-sm-2.control-label.wrappable(for='tests') tests:
.col-sm-10
textarea#tests.form-control(name="tests", rows=5, placeholder="Separate tests by a newline.")
.form-group
.col-sm-offset-2.col-sm-10
input.btn.btn-default(type='submit', value="submit")