Skip to content

Instantly share code, notes, and snippets.

@refractalize
Last active March 28, 2018 08:50
Show Gist options
  • Save refractalize/729b3ac84b753b43f719a0a9c284644f to your computer and use it in GitHub Desktop.
Save refractalize/729b3ac84b753b43f719a0a9c284644f to your computer and use it in GitHub Desktop.
#! /usr/bin/env node
const Calculator = require('./Calculator')
const calculator = new Calculator()
const [a, b] = process.argv.slice(2)
console.log(calculator.add(Number(a), Number(b)))
module.exports = class Calculator {
add (a, b) {
return a + b
}
}
const child_process = require('child_process')
const {promisify} = require('util')
const exec = promisify(child_process.exec)
module.exports = class CommandLineSetup {
setup () {
}
teardown () {
}
user () {
return {
assertAddCalculation: async (a, b, result) => {
const actualResult = Number((await exec(__dirname + `/calc ${a} ${b}`)).stdout.trim())
if (result !== actualResult) {
throw new Error(`expected calculator result ${result} but was ${actualResult}`)
}
}
}
}
}
const Calculator = require('./Calculator')
module.exports = class CoreSetup {
setup () {
this.calculator = new Calculator()
}
teardown () {
delete this.calculator
}
user () {
return {
assertAddCalculation: async (a, b, result) => {
const actualResult = this.calculator.add(a, b)
if (result !== actualResult) {
throw new Error(`expected calculator result ${result} but was ${actualResult}`)
}
}
}
}
}
const setups = [
require('./CommandLineSetup'),
require('./CoreSetup'),
require('./HttpApiSetup')
]
module.exports = function describeFeature(name, definition) {
describe(name, () => {
setups.forEach(Setup => {
describe(Setup.name, () => {
definition(Setup)
})
})
})
}
const Calculator = require('./Calculator')
const express = require('express')
const app = express()
app.get('/add', (req, res) => {
const {a, b} = req.query
const calculator = new Calculator()
const result = calculator.add(Number(a), Number(b))
res.json(result)
})
module.exports = app
const httpApi = require('./httpApi')
const httpism = require('httpism')
const {promisify} = require('util')
module.exports = class HttpApiSetup {
async setup () {
const listen = promisify((...args) => this.server = httpApi.listen(...args))
await listen(4567)
}
async teardown () {
const close = promisify(this.server.close).bind(this.server)
await close()
delete this.server
}
user () {
return {
assertAddCalculation: async (a, b, result) => {
const actualResult = await httpism.get(`http://localhost:4567/add`, {params: {a, b}})
if (result !== actualResult) {
throw new Error(`expected calculator result ${result} but was ${actualResult}`)
}
}
}
}
}
adding numbers
CommandLineSetup
✓ can add two numbers (91ms)
✓ can add a positive and negative number (90ms)
CoreSetup
✓ can add two numbers
✓ can add a positive and negative number
HttpApiSetup
✓ can add two numbers
✓ can add a positive and negative number
6 passing (225ms)
const describeFeature = require('./describeFeature')
describeFeature('adding numbers', Setup => {
let user
beforeEach(async () => {
setup = new Setup()
await setup.setup()
user = setup.user()
})
afterEach(async () => {
await setup.teardown()
})
it('can add two numbers', async () => {
await user.assertAddCalculation(1, 2, 3)
})
it('can add a positive and negative number', async () => {
await user.assertAddCalculation(1, -2, -1)
})
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment