From 26c041826bb1819c6cad880e45bad0b1c87868cd Mon Sep 17 00:00:00 2001 From: Nathan Leniz Date: Sun, 25 Jan 2015 23:56:04 -0500 Subject: [PATCH] Fixed bonfire to not overwrite user entry point but still allow user error by not defining entry point, create web form to give challenge json back, improved layout of bonfire even more --- app.js | 2 + controllers/bonfire.js | 94 ++++++++++++++++++++++- public/css/main.less | 15 +++- public/js/lib/bonfire/bonfireFramework.js | 7 +- seed_data/bonfires.json | 9 +-- seed_data/challenge-hashes | 2 +- views/bonfire/generator.jade | 45 +++++++++++ 7 files changed, 162 insertions(+), 12 deletions(-) create mode 100644 views/bonfire/generator.jade diff --git a/app.js b/app.js index 1b00f76de3..24b87bf777 100644 --- a/app.js +++ b/app.js @@ -261,6 +261,8 @@ app.get( bonfireController.returnIndividualBonfire ); app.get('/bonfires', bonfireController.returnBonfire); +app.get('/bonfire/generator', bonfireController.returnGenerator); +app.post('/bonfire/generator', bonfireController.generateChallenge); // Unique Check API route app.get('/api/checkUniqueUsername/:username', userController.checkUniqueUsername); diff --git a/controllers/bonfire.js b/controllers/bonfire.js index b669452ab0..264c688281 100644 --- a/controllers/bonfire.js +++ b/controllers/bonfire.js @@ -95,4 +95,96 @@ exports.returnIndividualBonfire = function(req, res, next) { bonfireHash: bonfire[bonfireNumber]._id }); }); -}; \ No newline at end of file +}; + +/** + * Bonfire generator + */ +exports.returnGenerator = function(req, res) { + res.render('bonfire/generator', { + title: null, + name: null, + difficulty: null, + brief: null, + details: null, + tests: null, + challengeSeed: null, + challengeEntryPoint: null, + bonfireHash: randomString() + }); +}; + +/** + * Post for bonfire generation + */ + +function randomString() { + var chars = "0123456789abcdef"; + var string_length = 24; + var randomstring = ''; + for (var i=0; i 0) { + return elem; + } +} + +exports.generateChallenge = function(req, res) { + 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', ''); + + + var response = { + name: bonfireName, + tests: bonfireTests, + difficulty: bonfireDifficulty, + description: bonfireDescription, + challengeEntryPoint: bonfireEntryPoint, + challengeSeed: bonfireChallengeSeed, + bonfireNumber: 0, + _id: randomString() + }; + res.send(response); +} diff --git a/public/css/main.less b/public/css/main.less index 23fcc5c631..d9c9cd4ab0 100644 --- a/public/css/main.less +++ b/public/css/main.less @@ -579,7 +579,16 @@ form.code span { font-family: "Ubuntu Mono"; padding-bottom: 0px; margin-bottom: 0px; - height: auto; + height: 100%; +} + +.CodeMirror-linenumber { + font-size: 18px; + font-family: "Ubuntu Mono"; +} + +#mainEditorPanel { + height: 100%; } .big-error-icon { @@ -606,13 +615,15 @@ form.code span { } div.CodeMirror-scroll { - padding-bottom: 100px; + padding-bottom: 40px; } .test-vertical-center { margin-top: 15px; } + + //uncomment this to see the dimensions of all elements outlined in red //* { // border-color: red; diff --git a/public/js/lib/bonfire/bonfireFramework.js b/public/js/lib/bonfire/bonfireFramework.js index 45ac46ca0e..8d8705cf0c 100644 --- a/public/js/lib/bonfire/bonfireFramework.js +++ b/public/js/lib/bonfire/bonfireFramework.js @@ -7,7 +7,6 @@ var myCodeMirror = CodeMirror.fromTextArea(document.getElementById("codeEditor") lint: true, matchBrackets: true, autoCloseBrackets: true, - cursorHeight: 1, scrollbarStyle: 'null', lineWrapping: true, gutters: ["CodeMirror-lint-markers"], @@ -20,6 +19,7 @@ var myCodeMirror = CodeMirror.fromTextArea(document.getElementById("codeEditor") } }); var editor = myCodeMirror; +editor.setSize("100%", "auto"); // Default value for editor if one isn't provided in (i.e. a challenge) @@ -37,7 +37,8 @@ var nonChallengeValue = '/*Welcome to Bonfire, Free Code Camp\'s future CoderByt 'assert.deepEqual(test(), [1,4,9]);\n\n' + 'var foo = test();\n' + 'foo.should.be.a("array");\n\n' + - 'test();'; + 'test();\n' + + 'function test(str) {\r\n return str;\r\n}'; var codeOutput = CodeMirror.fromTextArea(document.getElementById("codeOutput"), { lineNumbers: false, @@ -106,6 +107,8 @@ function bonfireExecute() { var userJavaScript = myCodeMirror.getValue(); userJavaScript = removeComments(userJavaScript); userJavaScript = scrapeTests(userJavaScript); + // simple fix in case the user forgets to invoke their function + userJavaScript = challengeEntryPoint + ' ' + userJavaScript; submit(userJavaScript, function(cls, message) { if (cls) { codeOutput.setValue(message.error); diff --git a/seed_data/bonfires.json b/seed_data/bonfires.json index db847aecea..42778c1e5e 100644 --- a/seed_data/bonfires.json +++ b/seed_data/bonfires.json @@ -15,8 +15,7 @@ ], "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, - "challengeEntryPointNegate" : "meetBonfire(\"You can do this!\");" + "bonfireNumber": 0 }, { "_id" : "aaa48de84e1ecc7c742e1124", @@ -40,8 +39,7 @@ ], "challengeSeed": "function palindrome(str) {\n // Good luck!\n return true;\n}\n\n", "challengeEntryPoint": "palindrome(\"eye\");", - "bonfireNumber": 1, - "challengeEntryPointNegate" : "palindrome\\([^str].*\\;" + "bonfireNumber": 1 }, { "_id" : "ff0395860f5d3034dc0bfc94", @@ -79,8 +77,7 @@ ], "challengeSeed": "function telephoneCheck(str) {\n // Good luck!\n return true;\n}\n\n", "challengeEntryPoint": "telephoneCheck(\"555-555-5555\");", - "bonfireNumber": 2, - "challengeEntryPointNegate" : "palindrome\\([^str].*\\;" + "bonfireNumber": 2 } ] diff --git a/seed_data/challenge-hashes b/seed_data/challenge-hashes index ca100cb520..64932960ca 100644 --- a/seed_data/challenge-hashes +++ b/seed_data/challenge-hashes @@ -1,7 +1,7 @@ /* -"c3a4d278b9e760a0ffe8321f" + "aceca143b92049a4392a859e" "ce9394f67d413734758e27e4" "1369953ef6f03098cb60e2f7" diff --git a/views/bonfire/generator.jade b/views/bonfire/generator.jade new file mode 100644 index 0000000000..bc150870a1 --- /dev/null +++ b/views/bonfire/generator.jade @@ -0,0 +1,45 @@ +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/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='tests') tests: + .col-sm-10 + textarea#tests.form-control(name="tests", rows=5, placeholder="Separate tests by a newline.") + .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 + .col-sm-offset-2.col-sm-10 + input.btn.btn-default(type='submit', value="submit")