github からユーザを検索する
rethrow.js
'use strict';
const fetch = require('node-fetch');
const rl =
require('readline')
.createInterface({ input: process.stdin, output: process.stdout });
class HttpError extends Error {
constructor(response) {
super(`${response.status} for ${response.url}`);
this.name = 'HttpError';
this.response = response;
}
}
function loadJson(url) {
return fetch(url)
.then(response => {
if (response.status == 200) return response.json();
else throw new HttpError(response);
});
}
function demoGithubUser() {
rl.question('Enter a name? : ', name => {
return loadJson(`https://api.github.com/users/${name}`)
.then(user => {
console.log(`Full name: ${user.name}.`);
rl.close();
return user;
})
.catch(err => {
if (err instanceof HttpError && err.response.status == 404) {
console.log('No such user, please reenter.');
return demoGithubUser();
} else {
throw err;
}
});
});
}
demoGithubUser();
実行結果
mocha でテスト
3つテストがあります。それぞれ node
を立ち上げます。
test.js
'use strict';
const assert = require('assert');
const child_process = require('child_process');
let proc;
describe("rethrow", () => {
beforeEach(() =>
proc = child_process.spawn('node', ['./rethrow.js'], { stdio: 'pipe' })
)
it('should output a prompt.', done => {
proc.stdout.once('data', output => {
assert.equal(output, 'Enter a name? : ');
proc.stdin.end();
done();
});
});
it('should accept a name', done => {
proc.stdout.once('data', output => {
proc.stdin.write('matz\n');
proc.stdout.once('data', output => {
assert.equal(output, 'Full name: Yukihiro "Matz" Matsumoto.\n');
done();
});
});
})
it('should answer for user who is none', done => {
proc.stdout.once('data', output => {
proc.stdin.write('no-such-user\n');
proc.stdout.once('data', function (output) {
assert.equal(output, 'No such user, please reenter.\n');
proc.stdin.end();
done();
});
});
})
});
実行結果
参考にしたページ
- Async/await
- Mocking STDIN STDOUT in node
- Mocha - the fun, simple, flexible JavaScript test framework
追記
readline-sync 使ったほうが楽ジャマイカ?