diff --git a/public/stage1/tests.js b/public/stage1/tests.js
index 46f1ed45..9b2e2451 100644
--- a/public/stage1/tests.js
+++ b/public/stage1/tests.js
@@ -12,7 +12,7 @@ describe('ステージ1(意図した DOM 要素を取得できるようにな
// 'change me!' を document.getElementById(elementId) に
// 書き換え、ブラウザをリロードしてみてください。
var elementId = 'firebrick';
- var element = 'change me!';
+ var element = document.getElementById(elementId);
expect(element).to.be.instanceof(HTMLElement);
expect(element).to.have.property('id', elementId);
@@ -27,7 +27,7 @@ describe('ステージ1(意図した DOM 要素を取得できるようにな
// 'change me!' を書き換えてください。
var elementId = 'chocolate';
- var element = 'change me!';
+ var element = document.getElementById(elementId);
expect(element).to.be.instanceof(HTMLElement);
expect(element).to.have.property('id', elementId);
@@ -41,7 +41,7 @@ describe('ステージ1(意図した DOM 要素を取得できるようにな
// 'change me!' を書き換えてください。
var elementClassName = 'mediumseagreen';
- var elements = 'change me!';
+ var elements = document.getElementsByClassName(elementClassName);
expect(elements).to.have.length(1);
expect(elements[0]).to.have.property('className', elementClassName);
@@ -55,7 +55,7 @@ describe('ステージ1(意図した DOM 要素を取得できるようにな
// 'change me!' を書き換えてください。
var elementClassName = 'turquoise';
- var elements = 'change me!';
+ var elements = document.getElementsByClassName(elementClassName);
expect(elements).to.have.length(2);
expect(elements[0]).to.have.property('className', elementClassName);
@@ -70,7 +70,7 @@ describe('ステージ1(意図した DOM 要素を取得できるようにな
// 'change me!' を書き換えてください。
var elementTagName = 'blockquote';
- var elements = 'change me!';
+ var elements = document.getElementsByTagName(elementTagName);
expect(elements).to.have.length(1);
expect(elements[0]).to.have.property('tagName', elementTagName.toUpperCase());
@@ -93,7 +93,7 @@ describe('ステージ1(意図した DOM 要素を取得できるようにな
// すると、開発ツール上で
... が選択されます。
// このことから、7 番の赤色の要素の ID は brown だということがわかります。
// では、'change me!' を document.getElementById('brown') に書き換えてみましょう。
- var element = 'change me!';
+ var element = document.getElementById('brown');
expect(element).to.have.property(secret('vq'), secret('oebja'));
});
@@ -102,7 +102,7 @@ describe('ステージ1(意図した DOM 要素を取得できるようにな
it('8 番の橙色の要素が1つ取得できる', function() {
// 'change me!' を書き換えてください。
- var element = 'change me!';
+ var element = document.getElementById('darkorange');
expect(element).to.have.property(secret('vq'), secret('qnexbenatr'));
});
@@ -111,7 +111,7 @@ describe('ステージ1(意図した DOM 要素を取得できるようにな
it('9 番の緑色の要素が1つ取得できる', function() {
// 'change me!' を書き換えてください。
- var elements = 'change me!';
+ var elements = document.getElementsByClassName('limegreen');
expect(elements).to.have.length(1);
expect(elements[0]).to.have.property(secret('pynffAnzr'), secret('yvzrterra'));
@@ -121,7 +121,7 @@ describe('ステージ1(意図した DOM 要素を取得できるようにな
it('10 番の水色の要素が2つ取得できる', function() {
// 'change me!' を書き換えてください。
- var elements = 'change me!';
+ var elements = document.getElementsByClassName('mediumturquoise');
expect(elements).to.have.length(2);
expect(elements[0]).to.have.property(secret('pynffAnzr'), secret('zrqvhzghedhbvfr'));
@@ -135,7 +135,7 @@ describe('ステージ1(意図した DOM 要素を取得できるようにな
//
// なお、11 番の青色の要素は li 要素ではありません!
// よくみると、色がついているのはさらに内側の要素のようです。
- var elements = 'change me!';
+ var elements = document.getElementsByTagName('p');
expect(elements).to.have.length(1);
expect(elements[0]).to.have.property(secret('gntAnzr'), secret('C'));
@@ -152,7 +152,7 @@ describe('ステージ1(意図した DOM 要素を取得できるようにな
//
// 'change me!' を document.querySelector('#firebrick') に
// 書き換えてください。
- var element = 'change me!';
+ var element = document.querySelector('#firebrick');
expect(element).to.have.property(secret('vq'), secret('sveroevpx'));
@@ -164,7 +164,7 @@ describe('ステージ1(意図した DOM 要素を取得できるようにな
it('2 番の橙色の要素を querySelector を使って1つ取得できる', function() {
// 'change me!' を書き換えてください。
- var element = 'change me!';
+ var element = document.querySelector('#chocolate');
expect(element).to.have.property(secret('vq'), secret('pubpbyngr'));
@@ -176,7 +176,7 @@ describe('ステージ1(意図した DOM 要素を取得できるようにな
it('3 番の緑色の要素を querySelector を使って1つ取得できる', function() {
// 'change me!' を書き換えてください。
- var element = 'change me!';
+ var element = document.querySelector('.mediumseagreen');
expect(element).to.have.property(secret('pynffAnzr'), secret('zrqvhzfrnterra'));
});
@@ -185,7 +185,7 @@ describe('ステージ1(意図した DOM 要素を取得できるようにな
it('4 番の水色の要素を querySelectorAll を使って2つ取得できる', function() {
// 'change me!' を書き換えてください。
- var elements = 'change me!';
+ var elements = document.querySelectorAll('.turquoise');
expect(elements).to.have.length(2);
expect(elements[0]).to.have.property(secret('pynffAnzr'), secret('ghedhbvfr'));
@@ -196,7 +196,7 @@ describe('ステージ1(意図した DOM 要素を取得できるようにな
it('5 番の青色の要素を querySelector を使って1つ取得できる', function() {
// 'change me!' を書き換えてください。
- var element = 'change me!';
+ var element = document.querySelector('[title=steelblue]');
expect(element).to.have.property(secret('gntAnzr'), secret('OYBPXDHBGR'));
});
@@ -205,7 +205,7 @@ describe('ステージ1(意図した DOM 要素を取得できるようにな
it('6 番の紫色の要素を querySelector を使って1つ取得できる', function() {
// 'change me!' を書き換えてください。
- var element = 'change me!';
+ var element = document.querySelector('[data-js-training=blueviolet]');
expect(element).to.have.deep.property(secret('qngnfrg.wfGenvavat'),
secret('oyhrivbyrg'));
@@ -220,8 +220,7 @@ describe('ステージ1(意図した DOM 要素を取得できるようにな
//
// 'change me!' を '.js-training:nth-child(2) li'
// に書き換えてください。
- var selector = 'change me!';
-
+ var selector = 'ul + ul > li:first-child';
var element = document.querySelector(selector);
expect(selector).to.not.have.string('#');
expect(element).to.have.property(secret('vq'), secret('oebja'));
@@ -231,7 +230,7 @@ describe('ステージ1(意図した DOM 要素を取得できるようにな
it('8 番の橙色の要素を ID セレクタを使わずに1つ取得できる', function() {
// 'change me!' を書き換えてください。
- var selector = 'change me!';
+ var selector = 'ul + ul > li:nth-child(2)';
var element = document.querySelector(selector);
expect(selector).to.not.have.string('#');
@@ -245,7 +244,7 @@ describe('ステージ1(意図した DOM 要素を取得できるようにな
it('12 番の紫色の要素を、属性セレクタと :nth-child(N) セレクタを使わずに1つ取得できる', function() {
// 'change me!' を書き換えてください。
- var selector = 'change me!';
+ var selector = 'ul + ul > li:last-child';
var element = document.querySelector(selector);
expect(selector).to.not.match(/\[\s*name\s*[~\|\^\$\*]?=/);
@@ -265,7 +264,7 @@ describe('ステージ1(意図した DOM 要素を取得できるようにな
// 基本的な使い方は document.querySelectorAll と同じです。
//
// 'change me!' を $('#brown') に書き換えてください。
- var $element = 'change me!';
+ var $element = $('#brown');
expect($element).to.be.instanceof(jQuery);
expect($element).to.have.id(secret('oebja'));
@@ -275,7 +274,7 @@ describe('ステージ1(意図した DOM 要素を取得できるようにな
it('8 番の橙色の要素を jQuery を使って1つ取得できる', function() {
// 'change me!' を書き換えてください。
- var $element = 'change me!';
+ var $element = $('#darkorange');
expect($element).to.be.instanceof(jQuery);
expect($element).to.have.id(secret('qnexbenatr'));
@@ -288,7 +287,7 @@ describe('ステージ1(意図した DOM 要素を取得できるようにな
it('9 番の緑色の要素を jQuery を使って1つ取得できる', function() {
// 'change me!' を書き換えてください。
- var $element = 'change me!';
+ var $element = $('.limegreen');
expect($element).to.be.instanceof(jQuery);
expect($element).to.have.class(secret('yvzrterra'));
@@ -298,7 +297,7 @@ describe('ステージ1(意図した DOM 要素を取得できるようにな
it('10 番の水色の要素を jQuery を使って2つ取得できる', function() {
// 'change me!' を書き換えてください。
- var $element = 'change me!';
+ var $element = $('.mediumturquoise');
expect($element).to.be.instanceof(jQuery);
expect($element).to.have.length(2);
@@ -309,7 +308,7 @@ describe('ステージ1(意図した DOM 要素を取得できるようにな
it('11 番の青色の要素を jQuery を使って1つ取得できる', function() {
// 'change me!' を書き換えてください。
- var $element = 'change me!';
+ var $element = $('p');
expect($element).to.be.instanceof(jQuery);
expect($element).to.have.length(1);
@@ -320,7 +319,7 @@ describe('ステージ1(意図した DOM 要素を取得できるようにな
it('12 番の紫色の要素を jQuery を使って1つ取得できる', function() {
// 'change me!' を書き換えてください。
- var $element = 'change me!';
+ var $element = $('[data-js-training="darkorchid"]');
expect($element).to.be.instanceof(jQuery);
expect($element).to.have.length(1);
@@ -334,7 +333,7 @@ describe('ステージ1(意図した DOM 要素を取得できるようにな
it('動いている寿司要素を取得する', function() {
// 'change me!' を書き換えてください。
- var element = 'change me!';
+ var element = document.getElementsByTagName('x-flying-sushi-monster')[0];
expect(element).to.have.deep.property(
secret('grkgPbagrag'), '\uD83C\uDF63');
diff --git a/public/stage2/tests.js b/public/stage2/tests.js
index b430dfdc..9f370ad3 100644
--- a/public/stage2/tests.js
+++ b/public/stage2/tests.js
@@ -11,8 +11,8 @@ describe('ステージ2(意図した通りに DOM 要素の属性・テキス
//
// var element = document.getElementById('firebrick');
// element.textContent = element.textContent + element.textContent;
- var element = 'change me!';
-
+ var element = document.getElementById('firebrick');
+ element.textContent = element.textContent + element.textContent;
expect(element).to.have.property(secret('vq'), secret('sveroevpx'));
expect(element).to.have.deep.property(
@@ -24,7 +24,9 @@ describe('ステージ2(意図した通りに DOM 要素の属性・テキス
// ここにコードを記述してください。
// 変更した DOM 要素は element 変数に代入してください。
- var element = 'change me!';
+ var element = document.getElementById('chocolate');
+ element.textContent = element.textContent + element.textContent;
+
expect(element).to.have.property(secret('vq'), secret('pubpbyngr'));
@@ -40,8 +42,8 @@ describe('ステージ2(意図した通りに DOM 要素の属性・テキス
// ここにコードを記述してください。
// 変更した DOM 要素は element 変数に代入してください。
- var element = 'change me!';
-
+ var element = document.getElementsByClassName('mediumseagreen')[0];
+ element.style.backgroundColor = 'limegreen';
expect(element).to.have.property(
secret('pynffAnzr'), secret('zrqvhzfrnterra'));
@@ -58,8 +60,8 @@ describe('ステージ2(意図した通りに DOM 要素の属性・テキス
// ここにコードを記述してください。
// 変更した DOM 要素は element 変数に代入してください。
- var element = 'change me!';
-
+ var element = document.getElementsByClassName('turquoise')[0];
+ element.style.opacity = '0.5';
expect(element).to.have.property(
secret('pynffAnzr'), secret('ghedhbvfr'));
@@ -76,8 +78,8 @@ describe('ステージ2(意図した通りに DOM 要素の属性・テキス
// ここにコードを記述してください。
// 変更した DOM 要素は element 変数に代入してください。
- var element = 'change me!';
-
+ var element = document.getElementsByTagName('blockquote')[0];
+ element.style.transform = 'rotate(10deg)';
expect(element).to.have.property(
secret('gntAnzr'), secret('OYBPXDHBGR'));
@@ -97,7 +99,9 @@ describe('ステージ2(意図した通りに DOM 要素の属性・テキス
//
// なお、上に 20px 移動させる方法は複数ありますが、今回は top 属性を
// 使う方法を使ってください。
- var element = 'change me!';
+ var element = document.querySelector('[data-js-training="blueviolet"]');
+ element.style.position = 'relative';
+ element.style.top = '-20px';
expect(element).to.have.deep.property(
@@ -127,8 +131,8 @@ describe('ステージ2(意図した通りに DOM 要素の属性・テキス
//
// var $element = $('#brown');
// $element.text($element.text() + $element.text());
- var $element = 'change me!';
-
+ var $element = $('#brown');
+ $element.text($element.text() + $element.text());
expect($element).to.be.instanceof(jQuery);
expect($element).to.have.id(secret('oebja'));
@@ -140,8 +144,8 @@ describe('ステージ2(意図した通りに DOM 要素の属性・テキス
// ここにコードを記述してください。
// 変更した DOM 要素は $element 変数に代入してください。
- var $element = 'change me!';
-
+ var $element = $('#darkorange');
+ $element.text($element.text() + $element.text());
expect($element).to.be.instanceof(jQuery);
expect($element).to.have.id(secret('qnexbenatr'));
@@ -156,7 +160,8 @@ describe('ステージ2(意図した通りに DOM 要素の属性・テキス
// ここにコードを記述してください。
// 変更した DOM 要素は $element 変数に代入してください。
- var $element = 'change me!';
+ var $element = $('.limegreen');
+ $element.css({'background-color': 'mediumseagreen'});
expect($element).to.be.instanceof(jQuery);
@@ -173,7 +178,8 @@ describe('ステージ2(意図した通りに DOM 要素の属性・テキス
// ここにコードを記述してください。
// 変更した DOM 要素は $element 変数に代入してください。
- var $element = 'change me!';
+ var $element = $('.mediumturquoise');
+ $element.css({'opacity': '0.5'});
expect($element).to.be.instanceof(jQuery);
@@ -186,7 +192,8 @@ describe('ステージ2(意図した通りに DOM 要素の属性・テキス
// ここにコードを記述してください。
// 変更した DOM 要素は $element 変数に代入してください。
- var $element = 'change me!';
+ var $element = $('p');
+ $element.css({'transform': 'rotate(10deg)'});
expect($element).to.be.instanceof(jQuery);
@@ -205,7 +212,9 @@ describe('ステージ2(意図した通りに DOM 要素の属性・テキス
//
// なお、上に 20px 移動させる方法は複数ありますが、今回は top 属性を
// 使う方法を使ってください。
- var $element = 'change me!';
+ var $element = $('[data-js-training="darkorchid"]');
+ $element.css({'position': 'relative',
+ 'top': '-20px'});
expect($element).to.be.instanceof(jQuery);
diff --git a/public/stage3/tests.js b/public/stage3/tests.js
index fa3cb6f2..0c6ff7ef 100644
--- a/public/stage3/tests.js
+++ b/public/stage3/tests.js
@@ -11,7 +11,9 @@ describe('ステージ3(意図した通りに DOM 要素の構造を変更で
// var element = document.querySelector('#firebrick');
// var ghost = document.querySelector('.firebrick-ghost');
// element.removeChild(ghost);
-
+ var element = document.querySelector('#firebrick');
+ var ghost = document.querySelector('.firebrick-ghost');
+ element.removeChild(ghost);
var firebrick = document.getElementById('firebrick');
expect(firebrick.childNodes.length).to.equal(1);
@@ -22,6 +24,10 @@ describe('ステージ3(意図した通りに DOM 要素の構造を変更で
it('2 番の要素からインベーダー要素を除去する', function() {
// ここにコードを記述してください。
+ var element = document.querySelector('#chocolate');
+ var ghost = document.querySelector('.chocolate-space-invader');
+ element.removeChild(ghost);
+
var darkorange = document.getElementById('chocolate');
@@ -33,7 +39,13 @@ describe('ステージ3(意図した通りに DOM 要素の構造を変更で
it('3 番の要素の左右の幽霊要素をすべて除去する', function() {
// ここにコードを記述してください。
-
+ var element = document.querySelector('.mediumseagreen');
+ var ghosts = document.querySelectorAll('.mediumseagreen-ghosts');
+ var length = ghosts.length;
+ var i;
+ for (i = 0; i < length; i += 1) {
+ element.removeChild(ghosts[i]);
+ }
var darkorange = document.querySelector('.mediumseagreen');
expect(darkorange).to.have.property('textContent', '3\uD83C\uDF3F');
@@ -45,7 +57,8 @@ describe('ステージ3(意図した通りに DOM 要素の構造を変更で
elementToAdd.textContent = '\uD83D\uDC2C';
// 上の elementToAdd を追加するコードをここに記述してください。
-
+ var target = document.querySelector('.turquoise');
+ target.appendChild(elementToAdd);
var turquoise = document.querySelector('.turquoise');
expect(turquoise.childNodes.length).to.equal(2);
@@ -60,7 +73,8 @@ describe('ステージ3(意図した通りに DOM 要素の構造を変更で
// 上の elementToAdd を、5 番の青色の要素の最初に追加するコードを
// ここに記述してください。
-
+ var target = document.getElementsByTagName('blockquote')[0];
+ target.insertBefore(elementToAdd, target.firstChild);
var blockquote = document.querySelector('blockquote');
expect(blockquote.childNodes.length).to.equal(2);
@@ -79,7 +93,7 @@ describe('ステージ3(意図した通りに DOM 要素の構造を変更で
// ここに以下のコードを記述してください。
//
// $('.brown-ghost').remove();
-
+ $('.brown-ghost').remove();
var $brown = $('#brown');
expect($brown.children()).to.have.length(0);
@@ -90,7 +104,7 @@ describe('ステージ3(意図した通りに DOM 要素の構造を変更で
it('7 番の要素からインベーダー要素を除去する', function() {
// ここにコードを記述してください。
-
+ $('.darkorange-space-invader').remove();
var $darkorange = $('#darkorange');
expect($darkorange.children()).to.have.length(0);
@@ -104,7 +118,7 @@ describe('ステージ3(意図した通りに DOM 要素の構造を変更で
it('8 番の要素の左右の幽霊要素をすべて除去する', function() {
// ここにコードを記述してください。
-
+ $('.limegreen-ghosts').remove();
var $limegreen = $('.limegreen');
expect($limegreen).to.have.text('8\uD83C\uDF3F');
@@ -115,7 +129,7 @@ describe('ステージ3(意図した通りに DOM 要素の構造を変更で
var $elementToAdd = $('\uD83D\uDC2C');
// 上の $elementToAdd を追加するコードをここに記述してください。
-
+ $('.mediumturquoise').append($elementToAdd);
var $mediumturquoise = $('.mediumturquoise');
expect($mediumturquoise.children()).to.have.length(1);
@@ -127,7 +141,7 @@ describe('ステージ3(意図した通りに DOM 要素の構造を変更で
var $elementToAdd = $('\uD83D\uDC1F');
// 上の $elementToAdd を追加するコードをここに記述してください。
-
+ $('p').prepend($elementToAdd);
var $p = $('p');
expect($p.children()).to.have.length(1);
diff --git a/public/stage4/tests.js b/public/stage4/tests.js
index 599536b6..d202e0d6 100644
--- a/public/stage4/tests.js
+++ b/public/stage4/tests.js
@@ -23,6 +23,10 @@ describe('ステージ4(意図通りにイベントを利用できる)', fun
// });
//
// ここに上記のどちらかのコードを記述してください。
+ $('#firebrick').on('click', function(event) {
+ var $target = $(event.target);
+ $target.text(Number($target.text()) + 1);
+ });
var firebrick = document.getElementById('firebrick');
@@ -37,6 +41,10 @@ describe('ステージ4(意図通りにイベントを利用できる)', fun
it('2 番の要素の click イベントで要素内の数字を 1 ずつ小さくできる', function() {
// ここにコードを記述してください。
+ $('#chocolate').on('click', function(event) {
+ var $target = $(event.target);
+ $target.text(Number($target.text()) - 1);
+ });
var chocolate = document.getElementById('chocolate');
@@ -51,7 +59,14 @@ describe('ステージ4(意図通りにイベントを利用できる)', fun
it('3 番の要素の click イベントで要素を 10 度ずつ回転できる', function() {
// ここにコードを記述してください。
+ var $target = $('.mediumseagreen');
+ $target.on('click', (function(){
+ var angleDeg = 0;
+ return function(){
+ $target.css({'transform': 'rotate(' + (angleDeg += 10) + 'deg)'});
+ };
+ })());
var mediumseagreen = document.querySelector('.mediumseagreen');
mediumseagreen.dispatchEvent(createClickEvent());
@@ -67,7 +82,11 @@ describe('ステージ4(意図通りにイベントを利用できる)', fun
it('4 番の要素を入力された角度に回転できる', function() {
// ここにコードを記述してください。
-
+ var $target = $('.turquoise');
+ var $input = $target.find('input');
+ $input.on('change', function(){
+ $target.css({'transform': 'rotate(' + this.value + 'deg)'});
+ });
var turquoise = document.querySelector('.turquoise');
var turquoiseInput = turquoise.querySelector('input');
@@ -93,9 +112,16 @@ describe('ステージ4(意図通りにイベントを利用できる)', fun
// なお、expect(steelblue).to.be.null は上記のテストの要件を満たして
// いないので、正解ではありません。
- var steelblue = document.querySelector('.steelblue');
- expect(steelblue).to.have.property('textContent', '5 \uD83D\uDC33');
- done();
+ document.addEventListener('DOMContentLoaded', (function(){
+ var steelblue = document.querySelector('.steelblue');
+ expect(steelblue).to.have.property('textContent', '5 \uD83D\uDC33');
+ done();
+ }));
+ // window.addEventListener('load', (function(){
+ // var steelblue = document.querySelector('.steelblue');
+ // expect(steelblue).to.have.property('textContent', '5 \uD83D\uDC33');
+ // done();
+ // }));
});
});
});
diff --git a/public/stage5/tests.js b/public/stage5/tests.js
index 568548d3..759ac9b4 100644
--- a/public/stage5/tests.js
+++ b/public/stage5/tests.js
@@ -9,10 +9,10 @@ describe('ステージ5(意図通りに非同期処理を利用できる)',
//
// ここに下記のコードを記述してください。
//
- // promise.then(function(msg) {
- // expect(msg).to.equal('resolved!');
- // testDone();
- // });
+ promise.then(function(msg) {
+ expect(msg).to.equal('resolved!');
+ testDone();
+ });
});
@@ -27,6 +27,10 @@ describe('ステージ5(意図通りに非同期処理を利用できる)',
// ここにコードを記述してください。
+ promise.catch(function(msg) {
+ expect(msg).to.equal('rejected!');
+ testDone();
+ });
});
@@ -38,8 +42,7 @@ describe('ステージ5(意図通りに非同期処理を利用できる)',
var promise3 = createWaitPromise(messageFragments[2], 30);
// 作成した promise を promise 変数に代入してください。
- var promise = 'change me!';
-
+ var promise = Promise.all([promise1, promise2, promise3]);
return expect(promise).to.eventually.deep.equal(messageFragments);
});
@@ -52,7 +55,7 @@ describe('ステージ5(意図通りに非同期処理を利用できる)',
var promise3 = createWaitPromise(messageFragments[2], 30);
// 作成した promise を promise 変数に代入してください。
- var promise = 'change me!';
+ var promise = Promise.race([promise1, promise2, promise3]);
return expect(promise).to.eventually.equal(messageFragments[1]);
@@ -69,9 +72,9 @@ describe('ステージ5(意図通りに非同期処理を利用できる)',
//
// ここに下記のコードを記述してください。
//
- // var promisedFriends = fetch(api + username).then(function(res) {
- // return res.json();
- // });
+ var promisedFriends = fetch(api + username).then(function(res) {
+ return res.json();
+ });
return expect(promisedFriends).to.eventually.have.length(1)
@@ -84,7 +87,9 @@ describe('ステージ5(意図通りに非同期処理を利用できる)',
var username = 'Shen';
// 作成した promise を promisedFriends 変数に代入してください。
- var promisedFriends = 'change me!';
+ var promisedFriends = fetch(api + username).then(function(res) {
+ return res.json();
+ });
return expect(promisedFriends).to.eventually.have.length(2)
@@ -97,21 +102,134 @@ describe('ステージ5(意図通りに非同期処理を利用できる)',
var username = 'Shen';
// 作成した promise を promisedFriends 変数に代入してください。
- var promisedFriends = 'change me!';
+ var fetchFriends = function(friends){
+ return Promise.all(friends.map(function(friend){return fetchFriend(friend);}));
+ };
+ var fetchFriend = function(friend){
+ return fetch(api + friend).then(function(res) {
+ return res.json();
+ });
+ };
+ var promisedFriends = fetchFriends(["jisp", "TeJaS"])
+ .then(function(res){return Array.prototype.concat.apply([], res);});
return expect(promisedFriends).to.eventually.have.length(1)
.and.have.members(['TypeScript']);
});
- it.skip('/api/friends API を使って CoffeeScript の友人を再帰的に取得できる', function() {
+ it('/api/friends API を使って CoffeeScript の友人を再帰的に取得できる', function() {
// 難易度高いので、自信のある人だけ挑戦してください。
// it.skip の .skip を消せば、テストが走るようになります。
// 作成した promise を promisedFriends 変数に代入してください。
- var promisedFriends = 'change me!';
+ var api = '/api/friends/';
+ var promisedFriends = [];
+ var fetchFriendsRecursive = function(targets, list){
+ list = list || [];
+ return fetchFriends(targets).then(function(friends){
+ if (friends.length == 0) {
+ return list;
+ }
+ list = list.concat(friends);
+ return fetchFriendsRecursive(friends, list);
+ });
+ };
+
+ var fetchFriends = function(targets){
+ return Promise.all(targets.map(fetchFriend))
+ .then(flatMap);
+ };
+ var fetchFriend = function(target){
+ return fetch(api + target).then(function(res) {
+ return res.json();
+ });
+ };
+
+ var flatMap = function(list){
+ return Array.prototype.concat.apply([], list);
+ };
+ // 作成した promise を promisedFriends 変数に代入してください。
+ promisedFriends = fetchFriendsRecursive(['CoffeeScript']);
+
+ // /**
+ // * 友人を取得する。
+ // * @param {string} usernameToFetch 友人の取得対象のユーザー名。
+ // * @return {Thenable>} 友人の配列。
+ // */
+ // function getFriends(usernameToFetch) {
+ // return fetch(api + usernameToFetch)
+ // .then(function(response) {
+ // return response.json();
+ // });
+ // }
+
+ // /**
+ // * 配列または配列をもつ promise を展開し、平たい配列をもつ promise を
+ // * 返す。
+ // * @param {Array|T>} arrayOfPromisedArray promise または、
+ // * オブジェクトの配列。
+ // * @return {Thenable>} 平たい配列をもつ promise。
+ // * @template T
+ // */
+ // function flatMap(arrayOfPromisedArray) {
+ // return Promise.all(arrayOfPromisedArray)
+ // .then(function(arrayOfArray) {
+ // return arrayOfArray.reduce(function(flatArray, array) {
+ // // JavaScript には破壊的な配列結合がないので、
+ // // Array#push を悪用することが多いです。
+ // Array.prototype.push.apply(flatArray, array);
+ // return flatArray;
+ // }, []);
+ // });
+ // }
+
+ // /**
+ // * 配列を結合する関数を返す。この関数の実行前に、結合する配列の片方を
+ // * 指定する必要がある。
+ // * @param {Array} arrayA 関数の実行前に指定する、結合したい配列。
+ // * @return {function(Array): Array} arrayA と arrayB を結合する関数。
+ // * @template T
+ // */
+ // function concat(arrayA) {
+ // return function(arrayB) {
+ // return arrayA.concat(arrayB);
+ // };
+ // }
+
+ // /**
+ // * 友人を再帰的に取得する。
+ // * @param {string} usernameToFetch 友人の取得対象の名前。
+ // * @return {Thenable>} 友人名の配列をもつ promise。
+ // */
+ // function getFriendsRecursively(usernameToFetch) {
+ // return getFriends(usernameToFetch)
+ // .then(function(friends) {
+ // if (friends.length === 0) return friends;
+
+ // var promisedFriendsOfFriends = Promise.all(
+ // friends.map(getFriendsRecursively));
+
+ // return promisedFriendsOfFriends
+ // .then(flatMap)
+ // .then(concat(friends));
+ // });
+ // }
+
+ // /**
+ // * いい感じにメソッドチェーンの途中で値を出力する
+ // * @param なんか
+ // * @return なんか
+ // */
+ // function tap(object){
+ // console.log(object);
+ // return object;
+ // }
+
+ // 作成した promise を promisedFriends 変数に代入してください。
+ // promisedFriends = getFriendsRecursively('CoffeeScript');
return expect(promisedFriends).to.eventually.have.length(5)
.and.have.members([
@@ -127,7 +245,10 @@ describe('ステージ5(意図通りに非同期処理を利用できる)',
it('Github の mixi-inc の organization の情報を取得できる', function() {
// 作成した promise を mixiOrg 変数に代入してください。
- var mixiOrg = 'change me!';
+ var endpoint = 'http://api.github.com/';
+ var api = 'orgs/';
+ var name = 'mixi-inc';
+ var mixiOrg = fetch(endpoint + api + name).then(function(res){return res.json();});
return expect(mixiOrg).to.eventually.have.property('id', 1089312);
@@ -138,10 +259,13 @@ describe('ステージ5(意図通りに非同期処理を利用できる)',
it('Github API を使って、mixi-inc/JavaScriptTraining の情報を取得できる', function() {
var repository = 'mixi-inc/JavaScriptTraining';
+ var endpoint = 'http://api.github.com/';
+ var api = 'repos/';
+ var name = 'mixi-inc/';
+ var repos = 'JavaScriptTraining';
// 作成した promise を mixiRepo 変数に代入してください。
- var mixiRepo = 'change me!';
-
+ var mixiRepo = fetch(endpoint + api + name + repos).then(function(res){return res.json();});
return expect(mixiRepo).to.eventually.have.property('full_name', repository);
@@ -156,7 +280,37 @@ describe('ステージ5(意図通りに非同期処理を利用できる)',
var mostPopularRepos = 'change me!';
// 作成した promise を mostPopularRepos 変数に代入してください。
+ var queryString = function(params){
+ var str = [];
+ for(var p in params)
+ if (params.hasOwnProperty(p)) {
+ str.push(encodeURIComponent(p) + "=" + encodeURIComponent(params[p]));
+ }
+ return str.join("&");
+ };
+
+ var fetchMostPopularRepo = function(keyword){
+ var endpoint = 'http://api.github.com/';
+ var api = 'search/repositories?';
+ var params = {
+ q: keyword,
+ sort: 'star'
+ };
+ return fetch(endpoint + api + queryString(params)).then(function(res) {
+ return res.json();
+ });
+ };
+
+ var fetchMostPopularRepos = function(keywords){
+ return Promise.all(keywords.map(function(keyword){return fetchMostPopularRepo(keyword);}));
+ };
+ mostPopularRepos = fetchMostPopularRepos(languages).then(function(res){
+ var ret = res.map(function(repos){
+ return repos.items[0].name;
+ });
+ return ret;
+ });
return expect(mostPopularRepos).to.eventually.have.length(2)
.and.satisfy(function(names) {