Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

g11n-related infrastructure upgrade #56

Merged
merged 10 commits into from
Feb 21, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
.DS_Store
node_modules
node_modules
exercises/stylish_css/public/main.css
70 changes: 70 additions & 0 deletions exercises/good_old_form/exercise.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
var qs = require('querystring')
, through2 = require('through2')
, superagent = require('superagent')
, exercise = require('workshopper-exercise')()
, filecheck = require('workshopper-exercise/filecheck')
, execute = require('workshopper-exercise/execute')
, comparestdout = require('workshopper-exercise/comparestdout')
, rndport = require('../../lib/rndport');

// checks that the submission file actually exists
exercise = filecheck(exercise)

// execute the solution and submission in parallel with spawn()
exercise = execute(exercise)

// set up ports to be passed to submission and solution
exercise.addSetup(function(mode, callback) {
this.submissionPort = rndport()
this.solutionPort = this.submissionPort + 1

this.submissionArgs = [this.submissionPort]
this.solutionArgs = [this.solutionPort]

process.nextTick(callback)
})

// add a processor for both run and verify calls, added *before*
// the comparestdout processor so we can mess with the stdouts
exercise.addProcessor(function (mode, callback) {
this.submissionStdout.pipe(process.stdout)

// replace stdout with our own streams
this.submissionStdout = through2()
if (mode == 'verify')
this.solutionStdout = through2()

setTimeout(query.bind(this, mode), 500)

process.nextTick(function () {
callback(null, true)
})
})


// compare stdout of solution and submission
exercise = comparestdout(exercise)

// delayed for 500ms to wait for servers to start so we can start
// playing with them
function query (mode) {
var exercise = this

function connect (port, stream) {
var url = 'http://localhost:' + port + '/form'
var text = 'Express.js rocks!'.split('').reverse().join('');

superagent
.post(url)
.type('form')
.send({str: text})
.pipe(stream)
}

connect(this.submissionPort, this.submissionStdout)

if (mode == 'verify')
connect(this.solutionPort, this.solutionStdout)
}

module.exports = exercise
60 changes: 60 additions & 0 deletions exercises/good_old_form/problem.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
Write a route (`'/form'`) that processes HTML form input
(`<form><input name="str"/></form>`) and prints backwards the `str` value.

-----------------------------

## HINTS

To handle POST request use the `post()` method which is used the same way as `get()`:

```js
app.post('/path', function(req, res){...})
```

Express.js uses middleware to provide extra functionality to your web server.

Simply put, a middleware is a function invoked by Express.js before your own
request handler.

Middlewares provide a large variety of functionalities such as logging, serving
static files and error handling.

A middleware is added by calling `use()` on the application and passing the
middleware as a parameter.

To parse `x-www-form-urlencoded` request bodies Express.js can use `urlencoded()`
middleware from the `body-parser` module.

```js
var bodyparser = require('body-parser')
app.use(bodyparser.urlencoded({extended: false}))
```

Read more about Connect middleware here:

https://github.com/senchalabs/connect#middleware

The documentation of the body-parser module can be found here:

https://github.com/expressjs/body-parser

Here is how we can flip the characters:

```js
req.body.str.split('').reverse().join('')
```

-----------------------------

## NOTE

When creating your projects from scratch, install the `body-parser` dependency
with npm by running:

```sh
$ npm install body-parser
```

…in your terminal.

Again, the port to use is passed {appname} to the application as `process.argv[2]`.
71 changes: 71 additions & 0 deletions exercises/hello_world/exercise.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
var through2 = require('through2')
, superagent = require('superagent')
, exercise = require('workshopper-exercise')()
, filecheck = require('workshopper-exercise/filecheck')
, execute = require('workshopper-exercise/execute')
, comparestdout = require('workshopper-exercise/comparestdout')
, rndport = require('../../lib/rndport');

// checks that the submission file actually exists
exercise = filecheck(exercise)

// execute the solution and submission in parallel with spawn()
exercise = execute(exercise)

// set up ports to be passed to submission and solution
exercise.addSetup(function(mode, callback) {
this.submissionPort = rndport()
this.solutionPort = this.submissionPort + 1

this.submissionArgs = [this.submissionPort]
this.solutionArgs = [this.solutionPort]

process.nextTick(callback)
})

// add a processor for both run and verify calls, added *before*
// the comparestdout processor so we can mess with the stdouts
exercise.addProcessor(function (mode, callback) {
this.submissionStdout.pipe(process.stdout)

// replace stdout with our own streams
this.submissionStdout = through2()
if (mode == 'verify')
this.solutionStdout = through2()

setTimeout(query.bind(this, mode), 500)

process.nextTick(function () {
callback(null, true)
})
})


// compare stdout of solution and submission
exercise = comparestdout(exercise)

// delayed for 500ms to wait for servers to start so we can start
// playing with them
function query (mode) {
var exercise = this

function connect (port, stream) {
var url = 'http://localhost:' + port + '/home'

superagent.get(url)
.on('error', function (err) {
exercise.emit(
'fail'
, exercise.__('fail.connection', {address: url, message: err.message})
)
})
.pipe(stream)
}

connect(this.submissionPort, this.submissionStdout)

if (mode == 'verify')
connect(this.solutionPort, this.solutionStdout)
}

module.exports = exercise
26 changes: 26 additions & 0 deletions exercises/hello_world/problem.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
Create an Express.js app that outputs "Hello World! when somebody goes to `/home`.

The port number will be provided to you by {appname} as the first argument of
the application, ie. `process.argv[2]`.

-----------------------------

## HINTS

This is how we can create an Express.js app on port 3000, that responds with
a string on `'/'`:

```js
var express = require('express')
var app = express()
app.get('/', function(req, res) {
res.end('Hello World!')
})
app.listen(3000)
```

Please use `process.argv[2]` instead of a fixed port number:

```js
app.listen(process.argv[2])
```
72 changes: 72 additions & 0 deletions exercises/jade/exercise.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
var path = require('path')
, through2 = require('through2')
, superagent = require('superagent')
, exercise = require('workshopper-exercise')()
, filecheck = require('workshopper-exercise/filecheck')
, execute = require('workshopper-exercise/execute')
, comparestdout = require('workshopper-exercise/comparestdout')
, rndport = require('../../lib/rndport');

// checks that the submission file actually exists
exercise = filecheck(exercise)

// execute the solution and submission in parallel with spawn()
exercise = execute(exercise)

// set up ports to be passed to submission and solution
exercise.addSetup(function(mode, callback) {
this.submissionPort = rndport()
this.solutionPort = this.submissionPort + 1

this.submissionArgs = [this.submissionPort, path.join(__dirname, 'templates')]
this.solutionArgs = [this.solutionPort, path.join(__dirname, 'templates')]

process.nextTick(callback)
})

// add a processor for both run and verify calls, added *before*
// the comparestdout processor so we can mess with the stdouts
exercise.addProcessor(function (mode, callback) {
this.submissionStdout.pipe(process.stdout)

// replace stdout with our own streams
this.submissionStdout = through2()
if (mode == 'verify')
this.solutionStdout = through2()

setTimeout(query.bind(this, mode), 500)

process.nextTick(function () {
callback(null, true)
})
})


// compare stdout of solution and submission
exercise = comparestdout(exercise)

// delayed for 500ms to wait for servers to start so we can start
// playing with them
function query (mode) {
var exercise = this

function connect (port, stream) {
var url = 'http://localhost:' + port + '/home'

superagent.get(url)
.on('error', function (err) {
exercise.emit(
'fail'
, exercise.__('fail.connection', {address: url, message: err.message})
)
})
.pipe(stream)
}

connect(this.submissionPort, this.submissionStdout)

if (mode == 'verify')
connect(this.solutionPort, this.solutionStdout)
}

module.exports = exercise
51 changes: 51 additions & 0 deletions exercises/jade/problem.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
Create an Express.js app with a home page rendered by Jade template engine.

The homepage should respond to `/home`.

The view should show the current date using `toDateString`.

-----------------------------

## HINTS

The Jade template file index.jade is already provided:

```jade
h1 Hello World
p Today is #{date}.
```

This is how to specify path in a typical Express.js app when the folder is
`'templates'`:

```js
app.set('views', path.join(__dirname, 'templates'))
```

However, to use our `index.jade`, the path to `index.jade` will be provided as
`process.argv[3]`. You are welcome to use your own jade file!

To tell Express.js app what template engine to use, apply this line to the
Express.js configuration:

```js
app.set('view engine', 'jade')
```

Instead of Hello World's `res.end()`, the `res.render()` function accepts
a template name and presenter data:

```js
res.render('index', {date: new Date().toDateString()})
```

We use `toDateString()` to simply return the date in a human-readable format
without the time.

--------------------------------

## NOTE

When creating your projects from scratch, install the `jade` dependency with npm.

Again, the port to use is passed by {appname} to the application as `process.argv[2]`.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loading