diff --git a/README.md b/README.md
index e8c773e8..e69de29b 100644
--- a/README.md
+++ b/README.md
@@ -1,1675 +0,0 @@
-2日でできる JavaScriptTraining
-==============================
-
-JavaScript 初心者が JS の未来を見据えつつ、
-基礎をひととおり身に付けるための資料です。
-
-
-
-この README は `npm run presentation` で
-再生することができます。
-
-
-
-トレーニングの目標
-------------------
-
-
-
-このトレーニングの目標は、
-**モジュールを読み書きできるようになり、**
-自分の好きなモジュールを
-つくれるようになることです。
-
-
-
-トレーニングの前に、セットアップを
-終わらせてしまいましょう。
-
-
-
-セットアップ
-------------
-
-
-
-### 1. 環境をセットアップ
-
-この研修では [Google Chrome](https://www.google.co.jp/chrome/browser/desktop/index.html) を利用します。
-上のリンクから Chrome をインストールしてください。
-
-[Node.js](http://nodejs.jp/nodejs.org_ja/) も利用しています。
-こちらも上のリンクからインストールしてください。
-
-
-
-### 2. JavaScriptTraining を fork
-
-JavaScriptTraining の学習履歴を残すために、
-JavaScriptTraining リポジトリを fork します。
-
-画面右上にある fork ボタンを押してください。
-
-[
](http://mixi-inc.github.io/JavaScriptTraining/images/fork-button.png)
-
-
-
-### 3. 必要なものをダウンロード
-
-ここからはターミナル上での操作になります。
-リポジトリの URL をコピーし、下のコマンドを
-ターミナルで実行してください。
-
- git clone コピーしたURL
-
-
-
-### 4. セットアップ
-
-下のコマンドをターミナルで実行してください。
-
- cd JavaScriptTraining
- npm install
-
-
-
-### 5. webサーバーを立ち上げる
-
-下のコマンドをターミナルで実行してください。
-
-なお、トレーニング中はこのコマンドを
-終了しないでください。
-
- npm run serve
-
-
-
-### 6. トップページにアクセスする
-
-ブラウザから [http://localhost:8000](http://localhost:8000) へ
-アクセスしてください。
-
-トレーニングの一覧が表示されていれば完了です。
-
-
-
-トレーニング前レクチャー
-------------------------
-
-
-
-### JavaScript とは
-
-> JavaScript はウェブの言語です。
->
-> ウェブページにある特定の要素を
-> 操作する手段として始まりましたが、
-> 途方もなく成長しました。
->
-> (JavaScript パターン, O'Reilly)
-
-
-
-### JavaScript のすごいところ
-
-> クラスというものがなく、
-> 第一級オブジェクトである関数が
-> 多くの仕事に使われます。
->
-> (JavaScript パターン, O'Reilly)
-
-
-
-> Java や PHP が追加しはじめた
-> クロージャーや無名関数といった
-> 機能は、JavaScript 開発者が
-> 楽しんできた機能であり、
-> あるのが当然だと思われていました。
->
-> (JavaScript パターン, O'Reilly)
-
-
-
-### 楽しんできた機能???
-
-```javascript
-['Foo', 'Bar', 'Buz'].forEach(function(name) {
- console.log('hello ' + name);
-});
-```
-
-(クロージャーはトレーニングで扱います)
-
-
-
-### JavaScript はどこで動くのか
-
-- Web ブラウザ
-- Node.js, io.js
-
-JavaScript の特色のひとつは、ブラウザ上で
-動作するということです。ブラウザ上で動作できる
-言語はいくつかありますが、一般的に
-JavaScript がよく使われます。
-
-
-
-### いつ JavaScript を使うのか
-
-- Web ページに独自の動きをつけたいとき
-
- (一部は CSS でできます)
-
-- ページ遷移なしにサーバーと通信したいとき
-- パフォーマンスチューニング
-- フロントエンドエコシステム使いたいとき
-
- (タスクランナーとかパッケージマネージャ)
-
-
-
-### JavaScript を使うと…
-
-- アニメーションの例: [Si digital](http://sidigital.co/)
-- インタラクションの例: [Vim.js](http://coolwanglu.github.io/vim.js/emterpreter/vim.html)
-- Web API の例: [Google Map](https://www.google.co.jp/maps)
-
-
-
-JavaScript に会いにいこう
--------------------------
-
-
-
-### 1. 開発ツールを開く
-
-Chrome で [http://localhost:8000](http://localhost:8000) を開きます。
-
-Web ページの適当な場所で
-右クリック > 要素の検証
-
-または
-
-- Mac の人: ⌘ + ⌥ + i
-- Windows の人:Ctrl + Shift + i
-
-
-
-### 2. Console を開く
-
-開発ツールを選択し、Esc キーを
-数回おしてみてください。
-
-すると、下に Console が出てきます。
-この Console から、JavaScript を
-実行することができます。
-
-[
](http://mixi-inc.github.io/JavaScriptTraining/images/console.png)
-
-
-
-### 3. 何か実行してみる
-
-試しに `alert('Foo');` と実行してみてください。
-
-アラートポップアップが表示されます。
-
-
-
-### 4. 計算させてみる
-
-`1 + 1` や `'Foo' + 'Bar'` なども実行できますね。
-
-
-
-### 5. 変数代入・参照してみる
-
-変数代入・参照もできますね。
-
-```javascript
-var foo = 'bar';
-foo;
-```
-
-
-
-### 6. ブラウザオブジェクトをいじる
-
-ブラウザオブジェクトもいじってみましょう。
-
-```javascript
-document.title = 'あなたとjava 今すぐダウンロード';
-```
-
-Chrome のタブ名が書き変わりました。
-
-
-
-### 7. ページを再読み込みすると戻る
-
-ページを再読み込みしてみてください。
-
-これまでの変更はすべてリセットされます。
-(つまり、この方法で本番リリースは
-できないということですね!)
-
-
-
-### 8. JavaScript とここで会える
-
-- スクリプト読み込みパターン(推奨)
-
- <script src="foo.js"></script>
-
-- インラインパターン
-
- <script>alert('inline!');</script>
-
-- インラインイベントハンドラーパターン
-
- <img src="buz.png" onerror="alert('onerror!')">
-
-- ブックマークレットパターン
-
- <a href="javascript: alert('bookmarklet!')"></a>
-
-
-
-開発環境道場
-------------
-
-(あるいはポエム)
-
-
-
-JavaScript を効率的に書けるようにするために
-最低限の開発環境を整えます。
-
-
-
-JavaScript に精通していない人に
-「どんなツールを使ったらいいですか?」と
-聞かれることがよくあります。
-
-私は「構文ハイライトと lint を使うといいですよ」、
-と答えることにしています。
-
-[
](http://mixi-inc.github.io/JavaScriptTraining/images/syntax-error.png)
-
-
-
-ひとつエピソードを紹介します。
-
-
-
-JavaScript には静的型検査がないことや、
-記号が多い構文や、まずい仕様がいくつもあるので、
-ミスを犯しやすい言語の一つです。
-
-
-
-たとえば、JavaScript には `"use strict"` という
-宣言があります。この宣言は JavaScript の
-まずい仕様の一部をエラーにすることで修正を
-促す効果があり、よく記述を推奨される宣言です。
-
-
-
-あるプロジェクトで気を利かした
-プログラマーが `"use strict"` を
-新しいスクリプトで使い始めました。
-
-```javascript
-"use strict";
-
-// Do something...
-```
-
-これは、開発時のミスを早期発見できるように
-するよい方法です!
-
-
-
-しかし、リリース後、新しいスクリプトとは
-関係ないはずの JavaScript による
-メニューが動作しなくなっていました。
-
-なぜでしょうか?
-
-
-
-これは、パフォーマンスチューニングの一環で
-複数の JavaScript ファイルを結合していたこと、
-ファイルに対する `"use strict"` を利用していた
-ことの2つが原因となって起きた不具合です。
-
-`"use strict"` が結合された
-すべてのファイル全体に効くように
-なり、`"use strict"` に対応していない
-古いファイルがエラーを出すように
-なってしまっていたのでした。
-
-
-
-このエピソードは、いわゆる**初見殺し**です。
-
-「何それどうしてそんな仕様なの😱」
-と言いたくなりますね。
-
-
-
-悲しいことに、このような落とし穴は
-JavaScript の仕様・文化に数多く
-潜んでいます。
-
-これらのミスをどのようにしたら
-防げるのでしょうか?
-
-
-
-[ESLint](http://eslint.org/) や [JSHint](http://jshint.com/)、 [JSLint](http://www.jslint.com/) のような lint を
-使いましょう。
-
-たとえば、ESLint を実行すると
-下のような警告が出されます。これによって、
-潜在的な不具合をだいぶ減らせるようになるのです。
-
- Use the function form of "use strict".
- (関数形式の "use strict" を使ってね)
-
-
-
-ミスを防ぐためには、「頑張る」とか
-「注意する」のような精神論ではなく、
- lint によって防止することが必要です。
-あなたが JavaScript にまだ精通していないので
-あれば、真っ先にいれるべきは lint なのです。
-
-
-
-1. lint をかけてみる
-
- ターミナルで下のコマンドを実行してください。
- ESLint が実行されます。
-
- gulp lint-stage1
-
-2. 構文ハイライトを効かせる
-
- ほとんどのエディタは構文ハイライトを
- サポートしています。Vim のように
- 構文ハイライトが選べるのであれば、
- よりミスのわかりやすい構文ハイライトを
- 利用します。
-
-
-
-トレーニング
-------------
-
-
-
-### ステージ1
-
-DOM 要素を取得するトレーニング
-
-
-
-#### DOM とは
-
-Web ページは HTML のタグによって
-構成されています。
-
-[
](http://mixi-inc.github.io/JavaScriptTraining/images/github.png)
-[
](http://mixi-inc.github.io/JavaScriptTraining/images/github-elements.png)
-
-この 3D ビューを見ると、複数の HTML タグから
-Web ページが構成されていることがよくわかります。
-
-
-
-この HTML タグは下のような木構造をとっています。
-
-[
](http://mixi-inc.github.io/JavaScriptTraining/images/github-elements.png)
-[
](http://mixi-inc.github.io/JavaScriptTraining/images/github-tree.png)
-
-実際に、[mixi-inc/JavaScriptTraining](https://github.com/mixi-inc/JavaScriptTraining) を開き、
-開発コンソールのElement タブに表示されている
-構造を確認してみてください。
-
-
-
-DOM (Document Object Model) は、この HTML のタグを
-JavaScript の世界で操作することができる API です。
-
-HTML タグは、JavaScript の世界で
-DOM 要素というオブジェクトとして扱われます。
-
-
-
-[
](http://mixi-inc.github.io/JavaScriptTraining/images/github-tree.png)
-
-HTML のタグを JavaScript 側で操作するためには
-HTML のタグを HTML 文書から取り出し、
-JavaScript の世界へと取ってこなければなりません。
-
-このステージでは、HTML から DOM 要素を
-取得するという操作について学びます。
-
-
-
-HTML タグには、目印となるいくつかの情報が
-付属しています。たとえば、下の div タグには
-ID 属性が付属しています。
-
-```html
-
foo
-```
-
-JavaScript はこの目印を DOM API に渡すことで、
-DOM 要素を取得することができます。
-
-```javascript
-var div = document.getElementById('foo');
-```
-
-
-
-他にも CSS クラスやタグ名、その他の属性から、
-DOM 要素を取得することができます。
-
-```html
-foo
-```
-
-
-
-#### CSS セレクタについて
-
-また、目印の指定の仕方のひとつに、
-CSS セレクタがあります。
-
-たとえば、`foo` という ID のついたタグであれば、
-
-```html
-foo
-```
-
-```javascript
-var div = document.querySelector('#foo');
-```
-
-というように、ID の先頭に `#` をつけた
-IDセレクタ `#foo` で、取得したい DOM 要素を指示します。
-
-
-
-この方法の利点は、複雑な位置にある DOM 要素を
-取得することができるということでしょう。
-
-下の HTML の bar を包む `div` タグにあたる
-DOM 要素を取得する場合、
-
-```html
-
-```
-
-```javascript
-var div = document.querySelector('.foo div:last-child');
-```
-
-というように、CSS クラスセレクタ `.foo` に
-該当する要素の子要素を子孫セレクタ (スペース) で
-取得し、このうち `div` タグから CSS 疑似セレクタ
-`:last-child` にマッチするものを取得する
-という操作になります。
-
-
-
-図にすると、このようになります。
-
-[
](http://mixi-inc.github.io/JavaScriptTraining/images/css-selector-example.png)
-
-CSS セレクタについては、[MDN のCSS リファレンス](https://developer.mozilla.org/ja/docs/Web/CSS/Reference#Selectors) が
-参考になります。
-
-仕様を見ないと我慢ならぬ!という立派な方は、
-[セレクタ Level 3 仕様](http://standards.mitsue.co.jp/resources/w3c/TR/css3-selectors/) を見るとよいでしょう。
-
-
-
-#### 実習
-
-下のテストが green になるように、
-`public/stage1/tests.js` を
-修正してください。
-
-[http://localhost:8000/stage1/](http://localhost:8000/stage1/)
-
-
-
-#### クリアできたら
-
-Lint をかけてみましょう。
-
- gulp lint-stage1
-
-警告があれば、修正してみてください。
-
-
-
-### ステージ2
-
-DOM 要素の属性・テキストを変更する
-トレーニング
-
-
-
-このステージでは、スタイルの変更や
-表示文字列を変更するやり方を学びます。
-
-
-
-#### DOM 要素の属性・テキスト
-
-DOM 要素には、
-
-- 先ほど DOM API に渡した ID 属性
-- CSS クラス属性などの目印となる属性
-- 見た目を操作するスタイル属性
-
-などが付属しています。
-
-(DOM の属性の一覧は [MDN DOM リファレンス](https://developer.mozilla.org/ja/docs/DOM/DOM_Reference) を
-参照してください)
-
-
-
-このうち、スタイル属性を編集すると、DOM 要素の
-見た目を変化させることができます。
-
-たとえば、Github のヘッダの octocat の
-style.color 属性を変更してみました。
-
-[
](http://mixi-inc.github.io/JavaScriptTraining/images/octocats.png)
-
-
-
-このスタイル属性は CSS の仕様と対応するように
-定められています。
-
-ただ、アニメーションを含め、見た目の変更は
-CSS クラス名の追加/編集/削除によっておこなう
-ことが推奨されてきています。
-
-([レンダリングエンジンによる最適化が効くのです!](https://developer.mozilla.org/ja/docs/Web/Guide/CSS/Using_CSS_animations))
-
-JavaScript は見た目の変更のきっかけを
-与えるだけにとどめるのが、上手な
-HTML/JavaScript/CSS 分業の基本です。
-
-
-
-残念なお知らせですが、
-今回のトレーニングは CSS を
-書けるようになることが目的ではないので、
-レガシーな element.style を編集するやり方を
-学びます。
-
-
-
-レガシー… 😱
-
-
-
-まあ、肩を落とさないでください。
-
-レガシーとはいえ、レガシーブラウザーを
-相手にするライブラリを読み書きするときには、
-どうしても必要になります。
-
-ちなみに、「レガシー?帰らせていただきます」は
-フロントエンドエンジニアとして大切な感覚ですので
-大事にしてください。
-
-
-
-#### 実習
-
-下のテストが green になるように、
-`public/stage2/tests.js` を
-修正してください。
-
-[http://localhost:8000/stage2/](http://localhost:8000/stage2/)
-
-
-
-#### クリアできたら
-
-Lint をかけてみましょう。
-
- gulp lint-stage2
-
-警告があれば、修正してみてください。
-
-
-
-### ステージ3
-
-DOM の構造を変更するトレーニング
-
-
-
-#### DOM の構造
-
-このステージでは、DOM の属性ではなく、
-構造を変更するトレーニングをおこないます。
-
-たとえば、書籍を検索する Web API を使って、
-書籍検索サービスを開発することを例に、
-DOM の構造を変更する必要性を考えてみます。
-
-
-
-書籍検索サービスの API は、検索結果を
-下のように返したとしましょう。
-
-```javascript
-[
- {
- "title": "紅",
- "score": 5
- },
- {
- "title": "円環少女",
- "score": 5
- },
- {
- "title": "SHI-NO -シノ- 黒き魂の少女",
- "score": 5
- },
- ...
-]
-```
-
-
-
-このとき、画面に表示するために下のような HTML を
-追加することになります。
-
-```html
-
- -
-
紅
- ★★★★★
-
- -
-
円環少女
- ★★★★★
-
- -
-
SHI-NO -シノ- 黒き魂の少女
- ★★★★★
-
- ...
-
-```
-
-
-
-サーバー側で上のような HTML を
-生成してもよいのですが、
-JavaScript による DOM 構造の操作に
-よって実現させることができれば、
-軽快な書籍検索サービスをつくることができます。
-
-(ページのリロードが必要ないからですね!)
-
-
-
-このように、Web サービスの使いやすさを
-追求するためには、JavaScript による
-DOM 構造の操作が重要なのです。
-
-
-
-#### 実習
-
-下のテストが green になるように、
-`public/stage3/tests.js` を
-修正してください。
-
-[http://localhost:8000/stage3/](http://localhost:8000/stage3/)
-
-
-
-#### クリアできたら
-
-Lint をかけてみましょう。
-
- gulp lint-stage3
-
-警告があれば、修正してみてください。
-
-
-
-### ステージ4
-
-DOM イベントを利用するトレーニング
-
-
-
-### DOM イベント解説編
-
-ユーザーがボタンを押したり、
-検索欄に入力したとき、JavaScript は
-DOM イベントをうけとることができます。
-
-たとえば、下のボタンは click イベントを
-引きがねとして、DOM 構造を書き換えます。
-
-
-
-
-
-click イベント以外にも多様なイベントがあります:
-
-- dblclick: 要素上でダブルクリックされたとき
-- mousemove: 要素上でポインタが移動しているとき
-- scroll: 画面がスクロールされたとき
-- unload: 次のページに遷移する直前
-- keydown: キーボードが押されたとき
-- animationstart: CSS アニメーションが開始したとき
-- offline: ブラウザがオフラインになったとき
-
-ここに載っていないイベントの一覧は
-[MDN DOM イベントリファレンス](https://developer.mozilla.org/ja/docs/Web2/Reference/Events) を
-参照するとよいでしょう。
-
-
-
-試しに、このページを制御する JavaScript が
-監視しているイベントを見てみましょう。
-
-開発ツールを開き、Elements タブの中段にある
-Event Listeners タブを開いてみてください。
-
-
-
-[
](http://mixi-inc.github.io/JavaScriptTraining/images/chrome-dev-tool-event-debugging.png)
-
-たくさんのイベントが登録されていますね。
-
-では、これらのイベントの使い方を解説していきます。
-
-
-
-#### DOM イベント実装編
-
-DOM のイベントを JavaScript 側で監視するには、
-いくつかの方法があります。
-
-- addEventListener スタイル
-
- ```javascript
- var button = document.getElementById('button');
- button.addEventListener('click', function(event) {
- console.log(event);
- });
- ```
-
-- インラインイベントハンドラースタイル
-
- ```html
-
- ```
-
-- イベント属性スタイル(レガシー)
-
- ```javascript
- var button = document.getElementById('button');
- button.onclick = function(event) {
- console.log(event);
- };
- ```
-
-
-
-このうち、 `addEventListener` スタイルが
-お行儀のよい方法だといわれ、
-推奨されてきました。
-
-```javascript
-// お行儀のよさ
-button.addEventListener('click', function(event) {
- console.log(event);
-});
-```
-
-
-
-しかし、[AngularJS](https://angularjs.org/) という最近の
-フレームワークでイベント属性スタイルを
-積極的に採用する動きもあります。
-
-```html
-
-
-
-
-
-```
-
-このような場合は、無理に `addEventListener` を
-使わずに、そのフレームワークのしきたりに
-従うとよいでしょう。
-
-
-
-### DOM イベント伝搬の仕組み
-
-次に、DOM のイベント伝搬(propagation)
-について解説します。
-
-
-
-下のようなボタンを例に、伝搬の必要性を
-考えていきます。このボタンは、アイコンつきで
-表示されることを意図しています。
-
-```html
-
-```
-
-この button 要素の `click` イベントを
-監視することを考えます。
-
-button 要素に `addEventListener` すればよいように
-見えますが、アイコン画像をクリックされた場合
-どうなるのでしょうか?
-
-
-
-実は、子要素で発生した DOM イベントは
-親要素からも監視することができます。
-
-この仕組みが DOM イベントの伝搬です。
-
-
-
-[
](http://www.w3.org/TR/DOM-Level-3-Events/#event-flow)
-
-
-
-`addEventListener` の引数で
-1-2-4 か 1-3-4 のどちらかを選べます。
-
-1. capturing フェーズ
-
- ルート要素からイベントの対象要素まで降りていく
-
-2. target フェーズ
-
- イベントの対象要素に到着
-
-3. bubbling フェーズ
-
- イベントの対象要素からルート要素まで昇っていく
-
-4. ブラウザ既定の処理がおこなわれるフェーズ
-
- リンクなどによる画面遷移がおこなわれる
-
-
-
-先ほどのボタンの例では、img 要素の
-click イベントは bubbling によって
-button 要素まで通知されるのです。
-
-```html
-
-```
-
-```javascript
-// button への addEventListener で OK
-button.addEventListener('click', function(event) {
- // Do something
-});
-```
-
-
-
-#### 実習
-
-下のテストが green になるように、
-`public/stage4/tests.js` を
-修正してください。
-
-[http://localhost:8000/stage4/](http://localhost:8000/stage4/)
-
-
-
-#### クリアできたら
-
-Lint をかけてみましょう。
-
- gulp lint-stage4
-
-警告があれば、修正してみてください。
-
-
-
-### ステージ5
-
-非同期処理のトレーニング
-
-
-
-JavaScript の美しい機能のひとつに
-非同期処理があります。
-
-下のコードは 1 秒まったあとに
-`console.log(1)` を実行するコードです。
-
-```javascript
-setTimeout(function() {
- console.log(1);
-}, 0);
-
-console.log(2);
-```
-
-このコードを実行すると、`1` と `2` の
-どちらか先に表示されるでしょうか。
-
-
-
-答えは、`2` です。`setTimeout` に登録された
-関数はいま実行途中のすべての関数が終了してから
-呼び出されます([JavaScriptのsetTimeoutを理解する](http://blog.mouten.info/2014/09/20/article/))。
-
-ここでは、関数を実行するタイミングを
-後回しにすることによって、待っている間に
-別のことができる、ということを覚えてください。
-
-この待ち時間の間に別の処理を実行する
-やり方を非同期処理と呼びます。
-
-
-
-#### サーバーとの通信
-
-非同期処理の代表例といえばサーバーとの通信です。
-
-サーバーとの通信はネットワークを通過するため、
-かなりの時間がかかります。そこで、レスポンスが
-返ってくるまでの間に、別の処理をおこなうことに
-よって、時間を有効活用することが重要になります。
-
-
-
-JavaScript にはサーバーと非同期に通信するための
-API が用意されています。
-
-- [Fetch API](http://www.hcn.zaq.ne.jp/___/WEB/Fetch-ja.html)
-
- 現在策定中の新しい標準仕様
-
-- [XMLHttpRequest](https://developer.mozilla.org/ja/docs/Web/API/XMLHttpRequest)
-
- jQuery.ajax のようなショートハンドが使われる
- ことが多く、実際手で書くことはほとんどない
-
-
-
-今回は、JavaScript の将来を見据えて、
-Fetch API によるサーバーとの通信を
-トレーニングします。
-
-
-
-#### Fetch API
-
-Fetch API は下のように書きます。
-このコードは、`/users.json` を
-取得します。
-
-```javascript
-fetch('/users.json')
- .then(function(response) {
- return response.json()
- })
- .then(function(json) {
- console.log('parsed json', json)
- })
- .catch(function(error) {
- console.error('parsing failed', error)
- });
-```
-
-`.then`、`.catch` という不思議なメソッドで
-つながっています。
-
-
-
-#### Promise を使った非同期処理
-
-さきほどの `.then`、`.catch` は、非同期処理の
-結果を、引数に渡した関数で受け取るために
-用意されています。
-
-たとえば、`.then` を使うと、正常にレスポンスが
-受け取れた場合に関数を実行できます。
-
-```javascript
-fetch('/users.json')
- .then(function(response) {
-
- // /users.json を正常に取得できたときに、
- // response をログに出力する
- console.log(response);
- });
-```
-
-エラーがあった場合は、ログ出力は実行されません。
-
-
-
-また、`.catch` を使うと、エラーが発生した場合に
-関数を実行できます。
-
-```javascript
-fetch('/users.json')
- .catch(function(errror) {
-
- // /users.json の取得時にエラーがでたときに、
- // error をログに出力する
- console.error(error);
- });
-```
-
-こちらは、正常にレスポンスを受け取れた場合は、
-ログ出力は実行されません。
-
-なお、先ほどの例のように `.then` と `.catch` を
-同時につけることもできます。
-
-
-
-サーバーと通信するだけなのに、
-なんか複雑すぎるような…?
-
-
-
-実はこの Promise という複雑な仕組みを使う理由は、
-
-- 並行非同期処理
-- 直列非同期処理
-
-を書きやすくする、ということなのです。
-
-
-
-#### Promise による平行非同期処理
-
-`Promise.all` を使います。
-
-```javascript
-// 2つの Web API からレスポンスが欲しい!
-
-Promise.all([
- fetch('/api/foo'),
- fetch('/api/bar')
-])
-.then(function(responses) {
- var responseFoo = responses[0];
- var responseBar = responses[1];
- doSomething(responseFoo, responseBar);
-});
-```
-
-
-
-#### Promise による直列非同期処理
-
-`.then` で次々に処理を連結できます。
-
-```javascript
-// Web API の結果を利用して別の API を実行したい!
-
-fetch('/api/foo')
- .then(doSomething)
- .then(function() { return fetch('/api/bar'); })
- .then(doSomething)
- .then(function() { return fetch('/api/buz'); })
- .then(doSomething);
-```
-
-
-
-#### 実習
-
-下のテストが green になるように、
-`public/stage5/tests.js` を
-修正してください。
-
-[http://localhost:8000/stage5/](http://localhost:8000/stage5/)
-
-
-
-#### 参考になる資料
-
-- [Promise に関する参考情報](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise)
-- [Promise 参考情報(重量級)](http://azu.github.io/promises-book/)
-- [Fetch API に関する参考情報](https://github.com/github/fetch)
-- [Github API に関する参考情報](https://developer.github.com/v3/)
-
-
-
-#### クリアできたら
-
-Lint をかけてみましょう。
-
- gulp lint-stage5
-
-警告があれば、修正してみてください。
-
-
-
-### ステージ6
-
-モジュールを実装するトレーニング
-
-
-
-JavaScript は言語機能としてモジュールの
-仕組みをもっていません。
-
-言語機能としてのモジュールシステムを利用するには
-[ECMAScript 6](https://developer.mozilla.org/ja/docs/Web/JavaScript/ECMAScript_6_support_in_Mozilla) を待たなければなりません。
-
-
-
-とはいっても、みんなモジュールを使いたかったので、
-さまざまなモジュールシステムとそれに付随する
-エコシステムが開発されてきました。
-
-
-
-- bower
-- component
-- jam
-- volo
-- npm with browserify
-- spm
-- jspm
-- duo
-
-(source: [wilmoore/frontend-packagers](https://github.com/wilmoore/frontend-packagers))
-
-
-
-あ…めっちゃ多い…😵
-
-
-
-今回は、利用方法がシンプルな「[bower](http://bower.io)」を使います。
-
-
-
-#### bower
-
-bower は、JavaScript、HTML、CSSなどを
-共有して使えるようにするフロントエンドの
-エコシステムです。
-
-他の人が作ったモジュールを利用することや、
-自分が作ったモジュールを公開することも
-できます。
-
-
-
-ただ、bower はモジュール読み込みの
-仕組みを提供していません。
-
-この部分は RequireJS など、別の
-モジュールシステムに頼ることになります。
-
-どのモジュールシステムに対応するかという選択は、
-bower によって読み込まれるパッケージ側に
-裁量(責務)があります。
-
-
-
-この方針を[公式ドキュメント](http://bower.io/#getting-started)は端的に
-言い表しています。
-
-> How you use packages is up to you.
->
-> (どのようにしてパッケージを使うのかはあなた次第です)
-
-
-
-#### 実習
-
-まず、bower を実行することを体験してみます。
-bower の設定ファイル bower.json を対話的に
-作成します。
-
- cd public/stage6/sample
- bower init
-
-
-
-あとは説明に従って選択していくと、bower の
-パッケージ設定ファイル `bower.json` が作成されます。
-
-
-
-##### 1. name
-
-このパッケージの名前を指定します。
-
-パッケージとして公開する場合には、既に同じ
-パッケージ名が存在していないか確かめる必要が
-あります。
-
-この研修では、公開/非公開を問わないので、
-お好きな名前をつけてください。
-
-
-
-##### 2. version
-
-このパッケージのバージョンを指定します。
-
-バージョンの形式は [Semantic Versioning](http://semver.org/lang/ja/) に
-準拠しています。
-
-この形式は、一般的に `X.Y.Z` と記述されます。
-
-- `X` は major version(後方互換性がなくなる変更)
-- `Y` は minor version(前方互換性がなくなる変更)
-- `Z` は patch version(バグ修正など)
-
-今回は開発版なので、0.0.0 にしておきましょう
-(major versionの 0 は開発版であることを示します)。
-
-
-
-##### 3. description
-
-パッケージの簡単な概要を記述します。
-
-有名どころの説明をみてみます。
-
-- bootstrap: The most popular HTML, CSS, and JavaScript framework for developing responsive, mobile first projects on the web.
-- angular-latest: HTML enhanced for web apps
-- less.js: Leaner CSS
-
-
-
-##### 4. main file
-
-このパッケージが外部のパッケージに公開したい
-ファイルを指定します。文字列と配列が指定できます。
-今回は空で問題ありません。
-
-
-
-##### 5. what types of module does this package expose?
-
-このパッケージが外部にエンドポイントを公開する
-方法を明示します。
-
-- amd: [Asynchronouse Module Definition](https://github.com/amdjs/amdjs-api/wiki/AMD) ([参考資料](http://www.matzmtok.com/blog/?p=845))
-- es6: [EcmaScript 6](http://wiki.ecmascript.org/lib/exe/fetch.php?id=harmony%3Aspecification_drafts&cache=cache&media=harmony:ecma-262_edition_6_03-17-15-releasecandidate3.pdf) ([参考資料](https://www.xenophy.com/javascript/8447#run-time-renaissance))
-- globals: グローバル変数経由でエンドポイント公開
-- node: [Node.js](https://nodejs.org/api/modules.html)
-- yui: [YUI](http://yuilibrary.com/yui/docs/yui/create.html) (メンテ停止したのでもうやめましょう)
-
-今回は何も選択しないで問題ありません。
-
-
-
-##### 6. keywords
-
-このパッケージを検索でヒットさせるための
-キーワードを指定します。
-
-
-
-##### 7. authors
-
-このパッケージの作者を指定します。
-
-
-
-##### 8. license
-
-好きなライセンスを選ぶとよいです。
-
-デフォルトは [MIT ライセンス](http://sourceforge.jp/projects/opensource/wiki/licenses%2FMIT_license)です。
-
-
-
-##### 9. homepage
-
-このパッケージの情報が見られる URL を記述します。
-
-
-
-##### 10. set currenttly installed components as dependencies?
-
-既に `bower_components` に含まれている
-コンポーネントをパッケージ設定に
-含まれるようにするかどうかを指定します。
-
-n で構いません。
-
-
-
-##### 11. add commonly ignored files to ignore list?
-
-`.gitignore` などのファイルから、
-パッケージに含めないファイルの指定を
-読み込むかどうか指定します。
-
-y で読み込ませます。
-
-
-
-##### 12. would you like to mark this package as private which prevents it from being accidentaly published to the registry?
-
-bower のレジストリへ登録できないようにするか
-どうか指定します。
-
-y でレジストリへの公開ができないように設定します。
-
-
-
-##### 13. Looks good?
-
-この設定で問題なければ y を入力します。
-
-
-
-##### bower install
-
-いよいよ、パッケージを追加していきます。
-
-パッケージは [Search Bower packages](http://bower.io/search/) で
-検索することができます。
-
-
-
-では、試しに [Buttons](https://github.com/alexwolfe/Buttons) パッケージを
-追加してみましょう。
-
-下のコマンドによって、Buttons パッケージが、
-`bower_components` 以下に配置されます。
-
- bower install --save Buttons
-
-
-
-`--save` はパッケージ設定に依存ファイルを
-追記する効果があります(`bower.json` の
-内容が変化しているので、見てみてください)。
-
-ここで設定に追記されたパッケージは、
-次回から `bower install` でまとめて
-取得することができるようになります。
-
-
-
-今回は、簡単のために script タグで直接
-`bower_components` 以下の JavaScript/CSS を
-読み込みます。
-
-
-
-今回の実習はテスト駆動形式ではありません。
-
-満足のいく Web アプリケーションが書けたら、
-`qualityOfYourAppliation` に `true` を
-代入してください。
-
-[http://localhost:8000/stage6/](http://localhost:8000/stage6/)
-
-
-
-#### クリアできたら
-
-Lint をかけてみましょう。
-
- gulp lint-stage6
-
-警告があれば、修正してみてください。
-
-
-
-### ステージ7
-
-よくあるイディオムを読むトレーニング
-
-
-
-このステージでは、よくある JavaScript の
-不思議な書き方を学びます。
-
-なお、今回はヒントがありません!
-ぜひ自分で調べて、結果を確かめてみてください!
-
-
-
-なお、興味のある方は、ステージ「闇」に
-挑戦してみてくださいね!
-
-`.skip` を削除すれば挑戦できるようにに
-なります。
-
-
-
-#### 実習
-
-下のテストが green になるように、
-`public/stage7/tests.js` を
-修正してください。
-
-[http://localhost:8000/stage7/](http://localhost:8000/stage7/)
-
-
-
-#### クリアできたら
-
-Lint をかけてみましょう。
-
- gulp lint-stage7
-
-警告があれば、修正してみてください。
-
-
-
-付録
-----
-
-
-
-### 解答・解説について
-
-解答は [2015-example-solution](https://github.com/mixi-inc/JavaScriptTraining/compare/2015...2015-example-solution) で見られます!
-
-
-
-### Promise について
-
-
-
-#### Promise による平行非同期処理
-
-Promise による平行非同期処理を通常のやりかたと、
-Promise らしいやり方とでやってみました。
-
-コードを比較してみてください。
-
-
-
-```javascript
-// 2つの Web API からレスポンスが欲しい!
-
-var done = { foo: false, bar: false };
-var responses = { foo: null, bar: false };
-fetch('/api/foo').then(function(responseFoo) {
- if (!done.bar) {
- done.foo = true;
- responses.foo = responseFoo;
- return;
- }
- doSomething(responseFoo, responses.bar);
-});
-fetch('/api/bar').then(function(responseBar) {
- if (!done.foo) {
- done.bar = true;
- responses.bar = responseFoo;
- return;
- }
- doSomething(responses.foo, responseBar);
-});
-```
-
-レスポンス取得の待ち合わせ処理があり、
-状態を複数もつ厄介なコードにしあがっていますね。
-
-
-
-```javascript
-// 2つの Web API からレスポンスが欲しい!
-
-Promise.all([
- fetch('/api/foo'),
- fetch('/api/bar')
-])
-.then(function(responses) {
- var responseFoo = responses[0];
- var responseBar = responses[1];
- doSomething(responseFoo, responseBar);
-});
-```
-
-`Promise.all` を使うと、待ち合わせ処理が
-なくスッキリ!
-
-
-
-#### Promise による直列非同期処理
-
-直列非同期処理についても、通常のやり方と、
-Promise らしいやり方でやってみました。
-
-コードを比較してみてください。
-
-
-
-```javascript
-// Web API の結果を利用して別の API を実行したい!
-
-fetch('/api/foo').then(function(responseFoo) {
- doSomething(responseFoo);
- fetch('/api/bar').then(function(responseBar) {
- doSomething(responseBar);
- fetch('/api/buz').then(function(responseBuz) {
- doSomething(responseBuz);
- });
- });
-});
-```
-
-コードがネストしているので、後ろの方の
-関数のスコープが深くなってしまっています。
-変数を追跡するのに手間がかかりそうです。
-
-
-
-ネストの外に出すだけならば、終了コールバックを
-呼び出す[継続渡しスタイル](http://ja.wikipedia.org/wiki/%E7%B6%99%E7%B6%9A%E6%B8%A1%E3%81%97%E3%82%B9%E3%82%BF%E3%82%A4%E3%83%AB) で
-書くことができます。
-
-```javascript
-// Web API の結果を利用して別の API を実行したい!
-
-fetch('/api/foo').then(callbackFoo);
-
-function callbackFoo(responseFoo) {
- doSomething(responseFoo);
- fetchBar(callbackBar);
-}
-
-function fetchBar(callback) {
- fetch('/api/bar').then(callback);
-}
-
-function callbackBar(responseBar) {
- doSomething(responseBar);
- fetchBuz(callbackBuz);
-}
-
-function fetchBuz(callback) {
- fetch('/api/buz').then(callback);
-}
-
-function callbackBuz(responseBuz) {
- doSomething(responseBuz);
-}
-```
-
-流れが追いづらい!
-
-
-
-クロージャー + 継続渡しスタイルを使うと…
-
-```javascript
-// Web API の結果を利用して別の API を実行したい!
-
-fetch('/api/foo').then(fetchBar(fetchBuz(doSomething)));
-
-function fetchBar(callback) {
- return function(responseFoo) {
- doSomething(responseFoo);
- fetchBar(callback);
- };
-}
-
-function fetchBuz(callback) {
- return function(responseBar) {
- doSomething(responseBar);
- fetchBuz(callback);
- };
-}
-```
-
-
-
-これはこれで美しい…😌
-
-(JS に慣れるまではちょっと読みづらいと思います)
-
-
-
-Promise らしいやり方をとると `.then` で
-次々に処理を連結できます。
-
-```javascript
-// Web API の結果を利用して別の API を実行したい!
-
-fetch('/api/foo')
- .then(doSomething)
- .then(function() { return fetch('/api/bar'); })
- .then(doSomething)
- .then(function() { return fetch('/api/buz'); })
- .then(doSomething);
-```
diff --git a/public/stage1/tests.js b/public/stage1/tests.js
index 46f1ed45..6489c7ef 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,8 @@ describe('ステージ1(意図した DOM 要素を取得できるようにな
//
// なお、11 番の青色の要素は li 要素ではありません!
// よくみると、色がついているのはさらに内側の要素のようです。
- var elements = 'change me!';
+ var elements = document.getElementsByTagName('p');
+ console.log(elements);
expect(elements).to.have.length(1);
expect(elements[0]).to.have.property(secret('gntAnzr'), secret('C'));
@@ -152,7 +153,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 +165,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 +177,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 +186,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 +197,7 @@ describe('ステージ1(意図した DOM 要素を取得できるようにな
it('5 番の青色の要素を querySelector を使って1つ取得できる', function() {
// 'change me!' を書き換えてください。
- var element = 'change me!';
+ var element = document.querySelector('.js-training li blockquote');
expect(element).to.have.property(secret('gntAnzr'), secret('OYBPXDHBGR'));
});
@@ -205,7 +206,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,7 +221,7 @@ describe('ステージ1(意図した DOM 要素を取得できるようにな
//
// 'change me!' を '.js-training:nth-child(2) li'
// に書き換えてください。
- var selector = 'change me!';
+ var selector = '.js-training:nth-child(2) li';
var element = document.querySelector(selector);
expect(selector).to.not.have.string('#');
@@ -231,7 +232,7 @@ describe('ステージ1(意図した DOM 要素を取得できるようにな
it('8 番の橙色の要素を ID セレクタを使わずに1つ取得できる', function() {
// 'change me!' を書き換えてください。
- var selector = 'change me!';
+ var selector = '.js-training:nth-child(2) li+li';
var element = document.querySelector(selector);
expect(selector).to.not.have.string('#');
@@ -245,7 +246,7 @@ describe('ステージ1(意図した DOM 要素を取得できるようにな
it('12 番の紫色の要素を、属性セレクタと :nth-child(N) セレクタを使わずに1つ取得できる', function() {
// 'change me!' を書き換えてください。
- var selector = 'change me!';
+ var selector = '.js-training [data-js-training="darkorchid"]';
var element = document.querySelector(selector);
expect(selector).to.not.match(/\[\s*name\s*[~\|\^\$\*]?=/);
@@ -265,7 +266,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 +276,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 +289,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 +299,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 +310,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 +321,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,8 +335,7 @@ describe('ステージ1(意図した DOM 要素を取得できるようにな
it('動いている寿司要素を取得する', function() {
// 'change me!' を書き換えてください。
- var element = 'change me!';
-
+ var element = document.querySelector('body > div:nth-child(11) > div');
expect(element).to.have.deep.property(
secret('grkgPbagrag'), '\uD83C\uDF63');
});
diff --git a/public/stage2/tests.js b/public/stage2/tests.js
index b430dfdc..4a0952ae 100644
--- a/public/stage2/tests.js
+++ b/public/stage2/tests.js
@@ -9,9 +9,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'));
@@ -24,7 +23,8 @@ 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 +40,8 @@ describe('ステージ2(意図した通りに DOM 要素の属性・テキス
// ここにコードを記述してください。
// 変更した DOM 要素は element 変数に代入してください。
- var element = 'change me!';
-
+ var element = document.querySelector('body > div:nth-child(1) > ul > li.mediumseagreen');
+ element.style.backgroundColor = 'limegreen';
expect(element).to.have.property(
secret('pynffAnzr'), secret('zrqvhzfrnterra'));
@@ -58,8 +58,8 @@ describe('ステージ2(意図した通りに DOM 要素の属性・テキス
// ここにコードを記述してください。
// 変更した DOM 要素は element 変数に代入してください。
- var element = 'change me!';
-
+ var element = document.querySelector('body > div:nth-child(1) > ul > li.turquoise');
+ element.style.opacity = '0.5';
expect(element).to.have.property(
secret('pynffAnzr'), secret('ghedhbvfr'));
@@ -76,7 +76,9 @@ describe('ステージ2(意図した通りに DOM 要素の属性・テキス
// ここにコードを記述してください。
// 変更した DOM 要素は element 変数に代入してください。
- var element = 'change me!';
+ var element = document.querySelector('body > div:nth-child(1) > ul > li:nth-child(5) > blockquote');
+ console.log(element);
+ element.style.transform = 'rotate(10deg)';
expect(element).to.have.property(
@@ -97,7 +99,12 @@ describe('ステージ2(意図した通りに DOM 要素の属性・テキス
//
// なお、上に 20px 移動させる方法は複数ありますが、今回は top 属性を
// 使う方法を使ってください。
- var element = 'change me!';
+ var element = document.querySelector('body > div:nth-child(1) > ul > li:nth-child(6)');
+ element.style.top = '-20px';
+ element.style.position = 'relative';
+ console.log(secret('qngnfrg.wfGenvavat'));
+ console.log(secret('fglyr.gbc'));
+ console.log(secret('fglyr.cbfvgvba'));
expect(element).to.have.deep.property(
@@ -125,10 +132,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 +145,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 +161,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 +179,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 +193,8 @@ describe('ステージ2(意図した通りに DOM 要素の属性・テキス
// ここにコードを記述してください。
// 変更した DOM 要素は $element 変数に代入してください。
- var $element = 'change me!';
+ var $element = $('body > div:nth-child(2) > ul > li:nth-child(5) > p');
+ $element.css('transform', 'rotate(10deg)');
expect($element).to.be.instanceof(jQuery);
@@ -205,7 +213,9 @@ describe('ステージ2(意図した通りに DOM 要素の属性・テキス
//
// なお、上に 20px 移動させる方法は複数ありますが、今回は top 属性を
// 使う方法を使ってください。
- var $element = 'change me!';
+ var $element = $('body > div:nth-child(2) > ul > li:nth-child(6)');
+ $element.css('top', '-20px');
+ $element.css('position', 'relative');
expect($element).to.be.instanceof(jQuery);
diff --git a/public/stage3/tests.js b/public/stage3/tests.js
index fa3cb6f2..df521b77 100644
--- a/public/stage3/tests.js
+++ b/public/stage3/tests.js
@@ -8,10 +8,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 +21,9 @@ describe('ステージ3(意図した通りに DOM 要素の構造を変更で
it('2 番の要素からインベーダー要素を除去する', function() {
// ここにコードを記述してください。
+ var element = document.getElementById('chocolate');
+ var invador = document.querySelector('.chocolate-space-invader');
+ element.removeChild(invador);
var darkorange = document.getElementById('chocolate');
@@ -32,7 +34,10 @@ describe('ステージ3(意図した通りに DOM 要素の構造を変更で
it('3 番の要素の左右の幽霊要素をすべて除去する', function() {
- // ここにコードを記述してください。
+ var element = document.querySelector('.mediumseagreen');
+ var ghost = document.querySelector('.mediumseagreen-ghosts');
+ element.removeChild(ghost);
+ element.removeChild(element.lastChild);
var darkorange = document.querySelector('.mediumseagreen');
@@ -45,6 +50,8 @@ describe('ステージ3(意図した通りに DOM 要素の構造を変更で
elementToAdd.textContent = '\uD83D\uDC2C';
// 上の elementToAdd を追加するコードをここに記述してください。
+ var element = document.querySelector('.turquoise');
+ element.appendChild(elementToAdd);
var turquoise = document.querySelector('.turquoise');
@@ -60,7 +67,9 @@ describe('ステージ3(意図した通りに DOM 要素の構造を変更で
// 上の elementToAdd を、5 番の青色の要素の最初に追加するコードを
// ここに記述してください。
-
+ var parent = document.querySelector('blockquote');
+ var child = parent.firstChild;
+ parent.insertBefore(elementToAdd, child);
var blockquote = document.querySelector('blockquote');
expect(blockquote.childNodes.length).to.equal(2);
@@ -78,7 +87,7 @@ describe('ステージ3(意図した通りに DOM 要素の構造を変更で
// jQuery でも同じことをおこなってみましょう。
// ここに以下のコードを記述してください。
//
- // $('.brown-ghost').remove();
+ $('.brown-ghost').remove();
var $brown = $('#brown');
@@ -90,7 +99,7 @@ describe('ステージ3(意図した通りに DOM 要素の構造を変更で
it('7 番の要素からインベーダー要素を除去する', function() {
// ここにコードを記述してください。
-
+ $('.darkorange-space-invader').remove();
var $darkorange = $('#darkorange');
expect($darkorange.children()).to.have.length(0);
@@ -104,6 +113,7 @@ describe('ステージ3(意図した通りに DOM 要素の構造を変更で
it('8 番の要素の左右の幽霊要素をすべて除去する', function() {
// ここにコードを記述してください。
+ $('.limegreen-ghosts').remove();
var $limegreen = $('.limegreen');
@@ -115,7 +125,7 @@ describe('ステージ3(意図した通りに DOM 要素の構造を変更で
var $elementToAdd = $('\uD83D\uDC2C');
// 上の $elementToAdd を追加するコードをここに記述してください。
-
+ $('.mediumturquoise').append($elementToAdd);
var $mediumturquoise = $('.mediumturquoise');
expect($mediumturquoise.children()).to.have.length(1);
@@ -127,7 +137,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..b72bdcdc 100644
--- a/public/stage4/tests.js
+++ b/public/stage4/tests.js
@@ -10,10 +10,10 @@ describe('ステージ4(意図通りにイベントを利用できる)', fun
//
// jQuery じゃない版:
//
- // var element = document.getElementById('firebrick');
- // element.addEventListener('click', function() {
- // element.textContent = Number(element.textContent) + 1;
- // });
+ var element = document.getElementById('firebrick');
+ element.addEventListener('click', function() {
+ element.textContent = Number(element.textContent) + 1;
+ });
//
// jQuery 版:
//
@@ -40,6 +40,10 @@ describe('ステージ4(意図通りにイベントを利用できる)', fun
var chocolate = document.getElementById('chocolate');
+ chocolate.addEventListener('click', function(){
+ chocolate.textContent = Number(chocolate.textContent) - 1;
+
+ });
chocolate.dispatchEvent(createClickEvent());
expect(chocolate).to.have.property('textContent', '1');
@@ -51,9 +55,12 @@ describe('ステージ4(意図通りにイベントを利用できる)', fun
it('3 番の要素の click イベントで要素を 10 度ずつ回転できる', function() {
// ここにコードを記述してください。
-
-
+ var nowDeg = 10;
var mediumseagreen = document.querySelector('.mediumseagreen');
+ mediumseagreen.addEventListener('click', function(){
+ mediumseagreen.style.transform = 'rotate(' + nowDeg + 'deg)';
+ nowDeg += 10;
+ });
mediumseagreen.dispatchEvent(createClickEvent());
expect(mediumseagreen).to.have.deep.property(
secret('fglyr.genafsbez'), secret('ebgngr(10qrt)'));
@@ -71,6 +78,10 @@ describe('ステージ4(意図通りにイベントを利用できる)', fun
var turquoise = document.querySelector('.turquoise');
var turquoiseInput = turquoise.querySelector('input');
+ turquoise.addEventListener('change', function(){
+ var deg = document.querySelector('body > div:nth-child(1) > ul > li.turquoise > input[type="number"]').value;
+ turquoise.style.transform = 'rotate(' + deg + 'deg)';
+ });
simulateChangeEvent(turquoiseInput, 10);
expect(turquoise).to.have.deep.property(
@@ -93,8 +104,10 @@ describe('ステージ4(意図通りにイベントを利用できる)', fun
// なお、expect(steelblue).to.be.null は上記のテストの要件を満たして
// いないので、正解ではありません。
- var steelblue = document.querySelector('.steelblue');
- expect(steelblue).to.have.property('textContent', '5 \uD83D\uDC33');
+ document.addEventListener('onload', 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..e028704e 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();
+ });
});
@@ -22,10 +22,10 @@ describe('ステージ5(意図通りに非同期処理を利用できる)',
// reject ハンドラーを使って、下の assertion が promise の
// エラー値を検証できるように記述してください。
//
- // expect(msg).to.equal('rejected!');
- // testDone();
-
- // ここにコードを記述してください。
+ promise.catch(function(msg){
+ expect(msg).to.equal('rejected!');
+ testDone();
+ });
});
@@ -38,7 +38,12 @@ 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 +57,11 @@ 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 +78,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 +93,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)
@@ -95,9 +106,30 @@ describe('ステージ5(意図通りに非同期処理を利用できる)',
it('/api/friends API を使って Shen の友人の友人を取得できる', function() {
var api = '/api/friends/';
var username = 'Shen';
+ // 答案を見た
+ // 友人を取得する
+ function getFriends(usernameTo){
+ return fetch(api + usernameTo)
+ .then(function(res){
+ return res.json();
+ });
+ }
+
+ // array => flatten
+ function flatMap(array){
+ return array.reduce(function(flatArray, a){
+ return flatArray.concat(a);
+ }, []);
+ }
// 作成した promise を promisedFriends 変数に代入してください。
- var promisedFriends = 'change me!';
+ var promisedFriends = getFriends(username)
+ .then(function(friends){
+ return Promise.all(friends.map(getFriends));
+ })
+ .then(function(friendsArray) {
+ return flatMap(friendsArray);
+ });
return expect(promisedFriends).to.eventually.have.length(1)
@@ -127,7 +159,10 @@ describe('ステージ5(意図通りに非同期処理を利用できる)',
it('Github の mixi-inc の organization の情報を取得できる', function() {
// 作成した promise を mixiOrg 変数に代入してください。
- var mixiOrg = 'change me!';
+ var mixiOrg = fetch('https://api.github.com/orgs/mixi-inc')
+ .then(function(res){
+ return res.json();
+ });
return expect(mixiOrg).to.eventually.have.property('id', 1089312);
@@ -140,7 +175,10 @@ describe('ステージ5(意図通りに非同期処理を利用できる)',
var repository = 'mixi-inc/JavaScriptTraining';
// 作成した promise を mixiRepo 変数に代入してください。
- var mixiRepo = 'change me!';
+ var mixiRepo = fetch('https://api.github.com/repos/' + repository)
+ .then(function(res){
+ return res.json();
+ });
return expect(mixiRepo).to.eventually.have.property('full_name', repository);
@@ -153,7 +191,30 @@ describe('ステージ5(意図通りに非同期処理を利用できる)',
it('Github API を使って、VimL、Emacs Lisp でスターが最も多いプロダクト名を' +
'それぞれ 1 つずつ取得できる', function() {
var languages = [ 'VimL', '"Emacs Lisp"' ];
- var mostPopularRepos = 'change me!';
+
+ function makeQuery(queryMap){
+ return Object.keys(queryMap)
+ .map(function(key) {
+ return encodeURIComponent(key) + '=' + encodeURIComponent(queryMap[key]);
+ })
+ .join('&');
+ }
+
+ function searchMostPopularRepoByLang(lang){
+ var queryString = makeQuery({
+ q: 'language:' + lang,
+ sort: 'stars'
+ });
+
+ return fetch('https://api.github.com/search/repositories?' + queryString)
+ .then(function(res){
+ return res.json();
+ })
+ .then(function(res){
+ return res.items[0].full_name;
+ });
+ }
+ var mostPopularRepos = Promise.all(languages.map(searchMostPopularRepoByLang));
// 作成した promise を mostPopularRepos 変数に代入してください。
diff --git a/public/stage6/sample/bower.json b/public/stage6/sample/bower.json
new file mode 100644
index 00000000..731d1c67
--- /dev/null
+++ b/public/stage6/sample/bower.json
@@ -0,0 +1,21 @@
+{
+ "name": "sample",
+ "version": "0.0.0",
+ "homepage": "https://github.com/jajkeqos/JavaScriptTraining",
+ "authors": [
+ "jajkeqos"
+ ],
+ "description": "sample test",
+ "license": "MIT",
+ "private": true,
+ "ignore": [
+ "**/.*",
+ "node_modules",
+ "bower_components",
+ "test",
+ "tests"
+ ],
+ "dependencies": {
+ "Buttons": "~2.0.0"
+ }
+}
diff --git a/public/stage6/tests.js b/public/stage6/tests.js
index 12920d31..70d30140 100644
--- a/public/stage6/tests.js
+++ b/public/stage6/tests.js
@@ -5,7 +5,7 @@ describe('ステージ6(意図通りにモジュールを書ける)', functi
// ボタンはサービスです。
// 自由に使ってください。
- var qualityOfYourAppliation = undefined;
+ var qualityOfYourAppliation = true;
expect(qualityOfYourAppliation).to.be.ok;
});
diff --git a/public/stage7/tests.js b/public/stage7/tests.js
index 3a72ba58..13ba1885 100644
--- a/public/stage7/tests.js
+++ b/public/stage7/tests.js
@@ -14,39 +14,39 @@ describe('ステージ7(よくあるJSのイディオムを読める)', func
it('1回目の値がわかる', function() {
- expect(counter()).to.equal(/* ここに値を書き込んでください */);
+ expect(counter()).to.equal(0/* ここに値を書き込んでください */);
});
it('2回目の値がわかる', function() {
- expect(counter()).to.equal(/* ここに値を書き込んでください */);
+ expect(counter()).to.equal(1/* ここに値を書き込んでください */);
});
it('3回目の値がわかる', function() {
- expect(counter()).to.equal(/* ここに値を書き込んでください */);
+ expect(counter()).to.equal(2/* ここに値を書き込んでください */);
});
});
describe('ショートサーキット演算', function() {
it("true && 'default' の結果がわかる", function() {
- expect(true && 'default').to.equal(/* ここに値を書き込んでください */);
+ expect(true && 'default').to.equal('default'/* ここに値を書き込んでください */);
});
it("false || 'default' の結果がわかる", function() {
- expect(false || 'default').to.equal(/* ここに値を書き込んでください */);
+ expect(false || 'default').to.equal('default'/* ここに値を書き込んでください */);
});
it("0 || 'default' の結果がわかる", function() {
- expect(0 || 'default').to.equal(/* ここに値を書き込んでください */);
+ expect(0 || 'default').to.equal('default'/* ここに値を書き込んでください */);
});
it("{} || 'default' の結果がわかる", function() {
- expect({} || 'default').to.deep.equal(/* ここに値を書き込んでください */);
+ expect({} || 'default').to.deep.equal({}/* ここに値を書き込んでください */);
});
@@ -55,7 +55,7 @@ describe('ステージ7(よくあるJSのイディオムを読める)', func
return arg || { foo: 'foo' };
};
- expect(func({ foo: 'bar' })).to.deep.equal(/* ここに値を書き込んでください */);
+ expect(func({ foo: 'bar' })).to.deep.equal({ foo: 'bar' }/* ここに値を書き込んでください */);
});
@@ -64,7 +64,7 @@ describe('ステージ7(よくあるJSのイディオムを読める)', func
return arg || { foo: 'foo' };
};
- expect(func()).to.deep.equal(/* ここに値を書き込んでください */);
+ expect(func()).to.deep.equal({ foo: 'foo'}/* ここに値を書き込んでください */);
});
});
@@ -76,7 +76,7 @@ describe('ステージ7(よくあるJSのイディオムを読める)', func
num = 1;
})();
- expect(num).to.equal(/* ここに値を書き込んでください */);
+ expect(num).to.equal(1/* ここに値を書き込んでください */);
});
@@ -87,7 +87,7 @@ describe('ステージ7(よくあるJSのイディオムを読める)', func
num = 1;
}, 0);
- expect(num).to.equal(/* ここに値を書き込んでください */);
+ expect(num).to.equal(0/* ここに値を書き込んでください */);
});
@@ -97,22 +97,22 @@ describe('ステージ7(よくあるJSのイディオムを読める)', func
it('!!truthy の結果がわかる', function() {
- expect(!!truthy).to.equal(/* ここに値を書き込んでください */);
+ expect(!!truthy).to.equal(true/* ここに値を書き込んでください */);
});
it('!!falsey の結果がわかる', function() {
- expect(!!falsey).to.equal(/* ここに値を書き込んでください */);
+ expect(!!falsey).to.equal(false/* ここに値を書き込んでください */);
});
it('Boolean(truthy) の結果がわかる', function() {
- expect(Boolean(truthy)).to.equal(/* ここに値を書き込んでください */);
+ expect(Boolean(truthy)).to.equal(true/* ここに値を書き込んでください */);
});
it('Boolean(falsey) の結果がわかる', function() {
- expect(Boolean(falsey)).to.equal(/* ここに値を書き込んでください */);
+ expect(Boolean(falsey)).to.equal(false/* ここに値を書き込んでください */);
});
});
@@ -137,71 +137,71 @@ describe('ステージ7(よくあるJSのイディオムを読める)', func
it('parent.grandParent の値がわかる', function() {
- expect(parent.grandParent).to.equal(/* ここに値を書き込んでください */);
+ expect(parent.grandParent).to.equal(true/* ここに値を書き込んでください */);
});
it('parent.child の値がわかる', function() {
- expect(parent.child).to.equal(/* ここに値を書き込んでください */);
+ expect(parent.child).to.equal(undefined/* ここに値を書き込んでください */);
});
it('child.grandParent の値がわかる', function() {
- expect(child.grandParent).to.equal(/* ここに値を書き込んでください */);
+ expect(child.grandParent).to.equal(true/* ここに値を書き込んでください */);
});
it('child.parent の値がわかる', function() {
- expect(child.parent).to.equal(/* ここに値を書き込んでください */);
+ expect(child.parent).to.equal(true/* ここに値を書き込んでください */);
});
});
});
-describe.skip('あなたの闇のJS力', function() {
+describe('あなたの闇のJS力', function() {
// .skip を外せば始められます
describe('ゆるふわ == 演算子', function() {
it("'10' == 10 の振る舞いがわかる", function() {
expect('10' == 10)
- .to.equal(/* ここに値を書き込んでください */);
+ .to.equal(true);
});
it('null == undefined の振る舞いがわかる', function() {
expect(null == undefined)
- .to.equal(/* ここに値を書き込んでください */);
+ .to.equal(true/* ここに値を書き込んでください */);
});
it('null == false の振る舞いがわかる', function() {
expect(null == false)
- .to.equal(/* ここに値を書き込んでください */);
+ .to.equal(false/* ここに値を書き込んでください */);
});
it('true == 1 の振る舞いがわかる', function() {
expect(true == 1)
- .to.equal(/* ここに値を書き込んでください */);
+ .to.equal(true/* ここに値を書き込んでください */);
});
it('true == 10 の振る舞いがわかる', function() {
expect(true == 10)
- .to.equal(/* ここに値を書き込んでください */);
+ .to.equal(false);
});
it('[0, 1] == 0 の振る舞いがわかる', function() {
expect([0, 1] == 0)
- .to.equal(/* ここに値を書き込んでください */);
+ .to.equal(false/* ここに値を書き込んでください */);
});
it('[1] == 1 の振る舞いがわかる', function() {
expect([1] == 1)
- .to.equal(/* ここに値を書き込んでください */);
+ .to.equal(true/* ここに値を書き込んでください */);
});
});
@@ -209,72 +209,72 @@ describe.skip('あなたの闇のJS力', function() {
describe('意図しない truthy/falsey', function() {
it('Boolean(false) が truthy/falsey のどちらなのかわかる', function() {
expect(Boolean(false) ? true : false)
- .to.equal(/* ここに値を書き込んでください */);
+ .to.equal(false/* ここに値を書き込んでください */);
});
it('Boolean(0) が truthy/falsey のどちらなのかわかる', function() {
expect(Boolean(0) ? true : false)
- .to.equal(/* ここに値を書き込んでください */);
+ .to.equal(false/* ここに値を書き込んでください */);
});
it('new Boolean(0) が truthy/falsey のどちらなのかわかる', function() {
expect(new Boolean(0) ? true : false)
- .to.equal(/* ここに値を書き込んでください */);
+ .to.equal(true/* ここに値を書き込んでください */);
});
it("'abc' が truthy/falsey のどちらなのかわかる", function() {
expect('abc' ? true : false)
- .to.equal(/* ここに値を書き込んでください */);
+ .to.equal(true/* ここに値を書き込んでください */);
});
it("'' が truthy/falsey のどちらなのかわかる", function() {
expect('' ? true : false)
- .to.equal(/* ここに値を書き込んでください */);
+ .to.equal(false/* ここに値を書き込んでください */);
});
it('String(0) が truthy/falsey のどちらなのかわかる', function() {
expect(String(0) ? true : false)
- .to.equal(/* ここに値を書き込んでください */);
+ .to.equal(true/* ここに値を書き込んでください */);
});
it("String('') が truthy/falsey のどちらなのかわかる", function() {
expect(String('') ? true : false)
- .to.equal(/* ここに値を書き込んでください */);
+ .to.equal(false/* ここに値を書き込んでください */);
});
it('new String(0) が truthy/falsey のどちらなのかわかる', function() {
expect(new String(0) ? true : false)
- .to.equal(/* ここに値を書き込んでください */);
+ .to.equal(true/* ここに値を書き込んでください */);
});
it("new String('') が truthy/falsey のどちらなのかわかる", function() {
expect(new String('') ? true : false)
- .to.equal(/* ここに値を書き込んでください */);
+ .to.equal(true/* ここに値を書き込んでください */);
});
});
describe('読めないキャスト万歳!', function() {
it("10 + '' の値がわかる", function() {
- expect(10 + '').to.equal(/* ここに値を書き込んでください */);
+ expect(10 + '').to.equal('10'/* ここに値を書き込んでください */);
});
it("+'10' の値がわかる", function() {
- expect(+'10').to.equal(/* ここに値を書き込んでください */);
+ expect(+'10').to.equal(10/* ここに値を書き込んでください */);
});
it("'10.1'|0 の値がわかる", function() {
- expect('10.1'|0).to.equal(/* ここに値を書き込んでください */);
+ expect('10.1'|0).to.equal(10/* ここに値を書き込んでください */);
});
@@ -282,51 +282,53 @@ describe.skip('あなたの闇のJS力', function() {
var obj = { length: 2, 0: 'foo', 1: 'bar' };
expect(Array.prototype.slice.call(obj))
- .to.deep.equal(/* ここに値を書き込んでください */);
+ .to.deep.equal(['foo', 'bar']/* ここに値を書き込んでください */);
});
it('+(new Date()) の型がわかる', function() {
expect(typeof +(new Date()))
- .to.equal(/* ここに値を書き込んでください */);
+ .to.equal('number'/* ここに値を書き込んでください */);
});
it('(new Date()) + 0 の型がわかる', function() {
expect(typeof ((new Date()) + 0))
- .to.equal(/* ここに値を書き込んでください */);
+ .to.equal('string'/* ここに値を書き込んでください */);
});
});
describe('ダブルスタンダード Array コンストラクタ', function() {
it('Array(3) が作成する配列の長さがわかる', function() {
- expect(Array(3)).to.have.length(/* ここに値を書き込んでください */);
+ expect(Array(3)).to.have.length(3/* ここに値を書き込んでください */);
});
it('Array(3) が作成する配列の0番目の要素がわかる', function() {
- expect(Array(3)[0]).to.equal(/* ここに値を書き込んでください */);
+ expect(Array(3)[0]).to.equal(undefined/* ここに値を書き込んでください */);
});
it('Array(3) が作成する配列がわかる', function() {
- expect(Array(3)).to.deep.equal(/* ここに値を書き込んでください */);
+ var array = [];
+ array.length = 3;
+ expect(Array(3)).to.deep.equal(array/* ここに値を書き込んでください */);
});
it('Array(1, 2, 3) が作成する配列の長さがわかる', function() {
- expect(Array(1, 2, 3)).to.have.length(/* ここに値を書き込んでください */);
+ expect(Array(1, 2, 3)).to.have.length(3/* ここに値を書き込んでください */);
});
it('Array(1, 2, 3) が作成する配列の0番目の要素がわかる', function() {
- expect(Array(1, 2, 3)[0]).to.equal(/* ここに値を書き込んでください */);
+ expect(Array(1, 2, 3)[0]).to.equal(1/* ここに値を書き込んでください */);
});
it('Array(1, 2, 3) が作成する配列がわかる', function() {
- expect(Array(1, 2, 3)).to.deep.equal(/* ここに値を書き込んでください */);
+ expect(Array(1, 2, 3)).to.deep.equal([1, 2, 3]/* ここに値を書き込んでください */);
});
});
@@ -336,7 +338,7 @@ describe.skip('あなたの闇のJS力', function() {
var obj = { foo: 'bar' };
with (obj) {
- expect(foo).to.equal(/* ここに値を書き込んでください */);
+ expect(foo).to.equal('bar'/* ここに値を書き込んでください */);
}
});
@@ -345,7 +347,7 @@ describe.skip('あなたの闇のJS力', function() {
var obj = { 'foo': 'bar', 'undefined': 'bar' };
with (obj) {
- expect(foo === undefined).to.equal(/* ここに値を書き込んでください */);
+ expect(foo === undefined).to.equal(true/* ここに値を書き込んでください */);
}
});
@@ -354,7 +356,7 @@ describe.skip('あなたの闇のJS力', function() {
var obj = { 'foo': 'bar', 'null': 'bar' };
with (obj) {
- expect(foo === null).to.equal(/* ここに値を書き込んでください */);
+ expect(foo === null).to.equal(false/* ここに値を書き込んでください */);
}
});
});
@@ -362,35 +364,35 @@ describe.skip('あなたの闇のJS力', function() {
describe('JavaScript のゆるふわ型判定', function() {
it('typeof 0 の結果がわかる', function() {
- expect(typeof 0).to.equal(/* ここに値を書き込んでください */);
+ expect(typeof 0).to.equal('number'/* ここに値を書き込んでください */);
});
it('typeof true の結果がわかる', function() {
- expect(typeof true).to.equal(/* ここに値を書き込んでください */);
+ expect(typeof true).to.equal('boolean'/* ここに値を書き込んでください */);
});
it("typeof 'string' の結果がわかる", function() {
- expect(typeof 'string').to.equal(/* ここに値を書き込んでください */);
+ expect(typeof 'string').to.equal('string'/* ここに値を書き込んでください */);
});
it('typeof function() {} の結果がわかる', function() {
- expect(typeof function() {}).to.equal(/* ここに値を書き込んでください */);
+ expect(typeof function() {}).to.equal('function'/* ここに値を書き込んでください */);
});
it('typeof {} の結果がわかる', function() {
- expect(typeof {}).to.equal(/* ここに値を書き込んでください */);
+ expect(typeof {}).to.equal('object'/* ここに値を書き込んでください */);
});
it('typeof [] の結果がわかる', function() {
- expect(typeof []).to.equal(/* ここに値を書き込んでください */);
+ expect(typeof []).to.equal('object'/* ここに値を書き込んでください */);
});
it('typeof undefined の結果がわかる', function() {
- expect(typeof undefined).to.equal(/* ここに値を書き込んでください */);
+ expect(typeof undefined).to.equal('undefined'/* ここに値を書き込んでください */);
});
it('typeof null の結果がわかる', function() {
- expect(typeof null).to.equal(/* ここに値を書き込んでください */);
+ expect(typeof null).to.equal('object'/* ここに値を書き込んでください */);
});
});
});