Permalink
Browse files

first 5 exercises converted to workshopper@1

  • Loading branch information...
1 parent 60d9575 commit 3ea6368b9ff3867a3ac6405408a3aaeeedd8d6b2 @rvagg rvagg committed Feb 14, 2014
Showing with 408 additions and 75 deletions.
  1. +15 −0 credits.js
  2. +1 −1 credits.txt
  3. +40 −0 exercises/baby_steps/exercise.js
  4. 0 {problems → exercises}/baby_steps/problem.md
  5. 0 problems/baby_steps/solution.js → exercises/baby_steps/solution/index.js
  6. +92 −0 exercises/filtered_ls/exercise.js
  7. 0 {problems → exercises}/filtered_ls/file-list.json
  8. 0 {problems → exercises}/filtered_ls/problem.md
  9. 0 {problems → exercises}/filtered_ls/setup.js
  10. 0 problems/filtered_ls/solution.js → exercises/filtered_ls/solution/index.js
  11. +17 −0 exercises/hello_world/exercise.js
  12. 0 {problems → exercises}/hello_world/problem.md
  13. 0 problems/hello_world/solution.js → exercises/hello_world/solution/index.js
  14. +1 −0 exercises/http_client/exercise.js
  15. 0 {problems → exercises}/http_client/problem.md
  16. 0 {problems → exercises}/http_client/setup.js
  17. 0 {problems → exercises}/http_client/solution.js
  18. +1 −0 exercises/http_client/solution/index.js
  19. +1 −0 exercises/http_collect/exercise.js
  20. 0 {problems → exercises}/http_collect/problem.md
  21. 0 {problems → exercises}/http_collect/setup.js
  22. 0 {problems → exercises}/http_collect/solution.js
  23. +1 −0 exercises/http_collect/solution/index.js
  24. +1 −0 exercises/http_file_server/exercise.js
  25. 0 {problems → exercises}/http_file_server/problem.md
  26. 0 {problems → exercises}/http_file_server/setup.js
  27. 0 {problems → exercises}/http_file_server/solution.js
  28. +1 −0 exercises/http_file_server/solution/index.js
  29. +1 −0 exercises/http_json_api_server/exercise.js
  30. 0 {problems → exercises}/http_json_api_server/problem.md
  31. 0 {problems → exercises}/http_json_api_server/setup.js
  32. 0 {problems → exercises}/http_json_api_server/solution.js
  33. +1 −0 exercises/http_json_api_server/solution/index.js
  34. +1 −0 exercises/http_uppercaserer/exercise.js
  35. 0 {problems → exercises}/http_uppercaserer/problem.md
  36. 0 {problems → exercises}/http_uppercaserer/setup.js
  37. 0 {problems → exercises}/http_uppercaserer/solution.js
  38. +1 −0 exercises/http_uppercaserer/solution/index.js
  39. +1 −0 exercises/juggling_async/exercise.js
  40. 0 {problems → exercises}/juggling_async/problem.md
  41. 0 {problems → exercises}/juggling_async/setup.js
  42. 0 {problems → exercises}/juggling_async/solution.js
  43. +1 −0 exercises/juggling_async/solution/index.js
  44. +1 −0 exercises/make_it_modular/exercise.js
  45. 0 {problems → exercises}/make_it_modular/problem.md
  46. 0 {problems → exercises}/make_it_modular/setup.js
  47. 0 {problems → exercises}/make_it_modular/solution.js
  48. +1 −0 exercises/make_it_modular/solution/index.js
  49. 0 {problems → exercises}/make_it_modular/solution_filter.js
  50. 0 {problems → exercises}/make_it_modular/verify.js
  51. 0 { → exercises}/menu.json
  52. +78 −0 exercises/my_first_async_io/exercise.js
  53. 0 {problems → exercises}/my_first_async_io/problem.md
  54. 0 problems/my_first_async_io/solution.js → exercises/my_first_async_io/solution/index.js
  55. +78 −0 exercises/my_first_io/exercise.js
  56. 0 {problems → exercises}/my_first_io/problem.md
  57. 0 problems/my_first_io/solution.js → exercises/my_first_io/solution/index.js
  58. +36 −0 exercises/my_first_io/wrap.js
  59. +1 −0 exercises/time_server/exercise.js
  60. 0 {problems → exercises}/time_server/problem.md
  61. 0 {problems → exercises}/time_server/setup.js
  62. 0 {problems → exercises}/time_server/solution.js
  63. +1 −0 exercises/time_server/solution/index.js
  64. +24 −7 learnyounode.js
  65. +11 −5 package.json
  66. +0 −11 problems/baby_steps/setup.js
  67. +0 −3 problems/hello_world/setup.js
  68. +0 −24 problems/my_first_async_io/setup.js
  69. +0 −24 problems/my_first_io/setup.js
View
@@ -0,0 +1,15 @@
+const fs = require('fs')
+ , path = require('path')
+ , colorsTmpl = require('colors-tmpl')
+
+
+function credits () {
+ fs.readFile(path.join(__dirname, './credits.txt'), 'utf8', function (err, data) {
+ if (err)
+ throw err
+
+ console.log(colorsTmpl(data))
+ })
+}
+
+module.exports = credits
View
@@ -1,4 +1,4 @@
-{yellow}{bold}{appname} is brought to you by the following dedicated hackers:{/bold}{/yellow}
+{yellow}{bold}learnyounode is brought to you by the following dedicated hackers:{/bold}{/yellow}
{bold}Name GitHub Username{/bold}
-----------------------------------
@@ -0,0 +1,40 @@
+var exercise = require('workshopper-exercise')()
+ , filecheck = require('workshopper-exercise/filecheck')
+ , execute = require('workshopper-exercise/execute')
+ , comparestdout = require('workshopper-exercise/comparestdout')
+
+
+// checks that the submission file actually exists
+exercise = filecheck(exercise)
+
+// execute the solution and submission in parallel with spawn()
+exercise = execute(exercise)
+
+// compare stdout of solution and submission
+exercise = comparestdout(exercise)
+
+
+// generate a random positive integer <= 100
+
+function rndint () {
+ return Math.ceil(Math.random() * 100)
+}
+
+
+exercise.addSetup(function (mode, callback) {
+ // mode == 'run' || 'verify'
+
+ // create a random batch of cmdline args
+ var args = [ rndint(), rndint() ]
+
+ while (Math.random() > 0.3)
+ args.push(rndint())
+
+ // supply the args to the 'execute' processor for both
+ // solution and submission spawn()
+ this.submissionArgs = this.solutionArgs = args
+
+ process.nextTick(callback)
+})
+
+module.exports = exercise
File renamed without changes.
@@ -0,0 +1,92 @@
+var fs = require('fs')
+ , path = require('path')
+ , os = require('os')
+ , exercise = require('workshopper-exercise')()
+ , filecheck = require('workshopper-exercise/filecheck')
+ , execute = require('workshopper-exercise/execute')
+ , comparestdout = require('workshopper-exercise/comparestdout')
+ , wrappedexec = require('workshopper-wrappedexec')
+ , after = require('after')
+ , rimraf = require('rimraf')
+ , files = require('./file-list')
+
+ , testDir = path.join(os.tmpDir(), '_learnyounode_' + process.pid)
+
+
+// checks that the submission file actually exists
+exercise = filecheck(exercise)
+
+// execute the solution and submission in parallel with spawn()
+exercise = execute(exercise)
+
+// compare stdout of solution and submission
+exercise = comparestdout(exercise)
+
+// wrap up the child process in a phantom wrapper that can
+// mess with the global environment and inspect execution
+exercise = wrappedexec(exercise)
+
+// a module we want run just prior to the submission in the
+// child process
+exercise.wrapModule(require.resolve('../my_first_io/wrap'))
+
+
+// set up the data file to be passed to the submission
+exercise.addSetup(function (mode, callback) {
+ // mode == 'run' || 'verify'
+
+ // supply the dir and extensions as args to the 'execute' processor for both
+ // solution and submission spawn()
+ // using unshift here because wrappedexec needs to use additional
+ // args to do its magic
+ this.submissionArgs.unshift('md')
+ this.submissionArgs.unshift(testDir)
+ this.solutionArgs.unshift('md')
+ this.solutionArgs.unshift(testDir)
+
+ fs.mkdir(testDir, function (err) {
+ if (err)
+ return callback(err)
+
+ var done = after(files.length, callback)
+
+ files.forEach(function (f) {
+ fs.writeFile(
+ path.join(testDir, f)
+ , 'nothing to see here'
+ , 'utf8'
+ , done
+ )
+ })
+ })
+})
+
+
+// add a processor only for 'verify' calls
+exercise.addVerifyProcessor(function (callback) {
+ var usedSync = false
+ , usedAsync = false
+
+ Object.keys(exercise.wrapData.fsCalls).forEach(function (m) {
+ if (/Sync$/.test(m)) {
+ usedSync = true
+ this.emit('fail', 'Used synchronous method: fs.' + m + '()')
+ } else {
+ usedAsync = true
+ this.emit('pass', 'Used asynchronous method: fs.' + m + '()')
+ }
+ }.bind(this))
+
+ callback(null, usedAsync && !usedSync)
+})
+
+
+// cleanup for both run and verify
+exercise.addCleanup(function (mode, passed, callback) {
+ // mode == 'run' || 'verify'
+
+ rimraf(testDir, callback)
+})
+
+
+module.exports = exercise
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,17 @@
+var exercise = require('workshopper-exercise')()
+ , filecheck = require('workshopper-exercise/filecheck')
+ , execute = require('workshopper-exercise/execute')
+ , comparestdout = require('workshopper-exercise/comparestdout')
+
+
+// checks that the submission file actually exists
+exercise = filecheck(exercise)
+
+// execute the solution and submission in parallel with spawn()
+exercise = execute(exercise)
+
+// compare stdout of solution and submission
+exercise = comparestdout(exercise)
+
+
+module.exports = exercise
File renamed without changes.
@@ -0,0 +1 @@
+// code stuff here
File renamed without changes.
File renamed without changes.
@@ -0,0 +1 @@
+// code stuff here
@@ -0,0 +1 @@
+// code stuff here
File renamed without changes.
@@ -0,0 +1 @@
+// code stuff here
@@ -0,0 +1 @@
+// code stuff here
@@ -0,0 +1 @@
+// code stuff here
@@ -0,0 +1 @@
+// code stuff here
@@ -0,0 +1 @@
+// code stuff here
@@ -0,0 +1 @@
+// code stuff here
@@ -0,0 +1 @@
+// code stuff here
@@ -0,0 +1 @@
+// code stuff here
@@ -0,0 +1 @@
+// code stuff here
@@ -0,0 +1 @@
+// code stuff here
@@ -0,0 +1 @@
+// code stuff here
File renamed without changes.
@@ -0,0 +1,78 @@
+var fs = require('fs')
+ , path = require('path')
+ , os = require('os')
+ , exercise = require('workshopper-exercise')()
+ , filecheck = require('workshopper-exercise/filecheck')
+ , execute = require('workshopper-exercise/execute')
+ , comparestdout = require('workshopper-exercise/comparestdout')
+ , wrappedexec = require('workshopper-wrappedexec')
+ , boganipsum = require('boganipsum')
+
+ , testFile = path.join(os.tmpDir(), '_learnyounode_' + process.pid + '.txt')
+
+
+// checks that the submission file actually exists
+exercise = filecheck(exercise)
+
+// execute the solution and submission in parallel with spawn()
+exercise = execute(exercise)
+
+// compare stdout of solution and submission
+exercise = comparestdout(exercise)
+
+// wrap up the child process in a phantom wrapper that can
+// mess with the global environment and inspect execution
+exercise = wrappedexec(exercise)
+
+// a module we want run just prior to the submission in the
+// child process
+exercise.wrapModule(require.resolve('../my_first_io/wrap'))
+
+
+// set up the data file to be passed to the submission
+exercise.addSetup(function (mode, callback) {
+ // mode == 'run' || 'verify'
+
+ var lines = Math.ceil(Math.random() * 50)
+ , txt = boganipsum({ paragraphs: lines })
+
+ // supply the file as an arg to the 'execute' processor for both
+ // solution and submission spawn()
+ // using unshift here because wrappedexec needs to use additional
+ // args to do its magic
+ this.submissionArgs.unshift(testFile)
+ this.solutionArgs.unshift(testFile)
+
+ // file with random text
+ fs.writeFile(testFile, txt, 'utf8', callback)
+})
+
+
+// add a processor only for 'verify' calls
+exercise.addVerifyProcessor(function (callback) {
+ var usedSync = false
+ , usedAsync = false
+
+ Object.keys(exercise.wrapData.fsCalls).forEach(function (m) {
+ if (/Sync$/.test(m)) {
+ usedSync = true
+ this.emit('fail', 'Used synchronous method: fs.' + m + '()')
+ } else {
+ usedAsync = true
+ this.emit('pass', 'Used asynchronous method: fs.' + m + '()')
+ }
+ }.bind(this))
+
+ callback(null, usedAsync && !usedSync)
+})
+
+
+// cleanup for both run and verify
+exercise.addCleanup(function (mode, passed, callback) {
+ // mode == 'run' || 'verify'
+
+ fs.unlink(testFile, callback)
+})
+
+
+module.exports = exercise
@@ -0,0 +1,78 @@
+var fs = require('fs')
+ , path = require('path')
+ , os = require('os')
+ , exercise = require('workshopper-exercise')()
+ , filecheck = require('workshopper-exercise/filecheck')
+ , execute = require('workshopper-exercise/execute')
+ , comparestdout = require('workshopper-exercise/comparestdout')
+ , wrappedexec = require('workshopper-wrappedexec')
+ , boganipsum = require('boganipsum')
+
+ , testFile = path.join(os.tmpDir(), '_learnyounode_' + process.pid + '.txt')
+
+
+// checks that the submission file actually exists
+exercise = filecheck(exercise)
+
+// execute the solution and submission in parallel with spawn()
+exercise = execute(exercise)
+
+// compare stdout of solution and submission
+exercise = comparestdout(exercise)
+
+// wrap up the child process in a phantom wrapper that can
+// mess with the global environment and inspect execution
+exercise = wrappedexec(exercise)
+
+// a module we want run just prior to the submission in the
+// child process
+exercise.wrapModule(require.resolve('./wrap'))
+
+
+// set up the data file to be passed to the submission
+exercise.addSetup(function (mode, callback) {
+ // mode == 'run' || 'verify'
+
+ var lines = Math.ceil(Math.random() * 50)
+ , txt = boganipsum({ paragraphs: lines })
+
+ // supply the file as an arg to the 'execute' processor for both
+ // solution and submission spawn()
+ // using unshift here because wrappedexec needs to use additional
+ // args to do its magic
+ this.submissionArgs.unshift(testFile)
+ this.solutionArgs.unshift(testFile)
+
+ // file with random text
+ fs.writeFile(testFile, txt, 'utf8', callback)
+})
+
+
+// add a processor only for 'verify' calls
+exercise.addVerifyProcessor(function (callback) {
+ var usedSync = false
+ , usedAsync = false
+
+ Object.keys(exercise.wrapData.fsCalls).forEach(function (m) {
+ if (/Sync$/.test(m)) {
+ usedSync = true
+ this.emit('pass', 'Used synchronous method: fs.' + m + '()')
+ } else {
+ usedAsync = true
+ this.emit('fail', 'Used asynchronous method: fs.' + m + '()')
+ }
+ }.bind(this))
+
+ callback(null, !usedAsync && usedSync)
+})
+
+
+// cleanup for both run and verify
+exercise.addCleanup(function (mode, passed, callback) {
+ // mode == 'run' || 'verify'
+
+ fs.unlink(testFile, callback)
+})
+
+
+module.exports = exercise
File renamed without changes.
Oops, something went wrong.

0 comments on commit 3ea6368

Please sign in to comment.