パルカワ2

最近はFlutterをやっています

Jestを使うことにした

Jest · 🃏 Delightful JavaScript Testing

  • ユニットテスト書きたい
  • DOM操作があるテストができる
  • 通信の処理があるのでモックとかもしたい
  • 導入がめんどくさくない

自分でkarma/jasmineの設定もしてみて先人の知恵のおかげで困りはしなかったんだけど、まあJestでええか…みたいな感じになった。

Jest+TypeScriptでDOMを操作するテストを書く

ここに書かれてる方法だと document がないよ!って言われる
DOM Manipulation · Jest
JSDOMでやってあげるとよさそう。

// Hoge.test.ts
import {JSDOM} from "jsdom";

declare global {
    namespace NodeJS {
        interface Global {
            document: Document
        }
    }
}

test('js dom', () => {
    global.document = new JSDOM(`<span id="username">yoshitaka-yuriko</span>`).window.document;
    expect(document.querySelector(`#username`).textContent).toBe("yoshitaka-yuriko")
});

ngrok を使う

自分向けにローカルにあるJSをhttps経由で配布したいが、自分であれこれ設定するのはだるい。ngrokというのがあるらしいので使ったらすぐできた。

ngrok は登録が必要で、登録するとコマンドのインストールや設定を促される。そのあと以下を実行するとよい

ngrok http 8000 -bind-tls=true

内容も瞬時に反映されるので便利 ちなみに手元のサーバはファイル配信のみなのでWebServer for Chromeを使った。

これが本来の用途っぽい?

api.slack.com

TypeScript の async/await

雰囲気でPromiseを使っていたが、雰囲気でTypeScriptを使い始め、雰囲気でasync/awaitを使い始めたが、よくわからないままだったので簡単に自分向けにまとめておく。 間違えていたら教えてほしい。ちなみにTSのtargetはes6

async をつけると

Promiseが返るようになるという認識

返り値

Promise.resolve() を返すかそのまま値を返すとよい。 Promise.resolve() が必要ないならわざわざラップして返す必要はなさそう。

 const t = async () => {
     return Promise.resolve("ok")
 };
 async function main() {
     await t().then(console.log);
     console.log("finish")
 }
 main();
 const t = async () => {
     return "ok"
 };
 async function main() {
     await t().then(console.log);
     console.log("finish")
 }
 main();
   const t = async () => {
       // returnしなくても次に進む
   };
   async function main() {
       await t().then(console.log);
       console.log("finish")
   }
   main();

エラーハンドリング

Promise.reject() を返すかthrowすればエラーが起きたことを知らせることが出来る。 try-catchを利用するので、エラーが起きた場合はthrowするのがわかりが良い気がする。

 const t = async () => {
     return Promise.reject(new Error("error!"))
 };
 async function main() {
     try {
       await t().then(console.log);
     } catch (error) {
         console.log("catch error", error)
     } finally {
       console.log("finish")
     }
 }
 main();
 const t = async () => {
     throw new Error("error!")
 };
 async function main() {
     try {
       await t().then(console.log);
     } catch (error) {
         console.log("catch error", error)
     } finally {
       console.log("finish")
     }
 }
 main();

また以下のようにthrowしただけであってもPromiseのcatchを使うことが可能である。 catchした場合は、try-catchのcatchには入らず、通常処理に戻る

  const t = async () => {
      throw new Error("error!")
  };
  async function main() {
      try {
        await t().catch(console.log)
        console.log("age") // 実行される
      } catch (error) {
          console.log("catch error", error)
      } finally {
        console.log("finish")
      }
  }
  main();

errorはなにも返さなくてもよい。 例えば Promise.reject() に何も渡さない場合catchされた error は undefined になる。エラーが起きたわけではないけど、なんらかの理由でこれ以上処理を進めたくない場合などに使うらしい。なるほど(Promiseのテクニック??)

 const t = async () => {
     return Promise.reject();
 };
 async function main() {
     try {
         await t()
         console.log("age") // 実行されない
     } catch (error) {
         console.log("catch error", error)
     } finally {
         console.log("finish")
     }
 }
 main();

個人的にはそれをやるならそれ用のエラーを作ったほうが明確でよいと思ったが好みかもしれない。

 class AbortError extends Error { 
 }
 const t = async () => {
     return Promise.reject(new AbortError("ほげほげだからAbortだよ"));
 };
 async function main() {
     try {
         await t()
         console.log("age")
     } catch (error) {
         if (error.constructor === AbortError) {
             console.log(error.message)
             return
         }
         console.log("catch error", error)
     } finally {
         console.log("finish")
     }
 }
 main();

HTMLにあるフォームをsubmitするのではなくfetchを使ってsubmitしたい

form.submit()するんじゃなくてfetchを使う必要があったのでやり方調べたらFromDataなるものがあった。便利

const form = document.querySelector("#form1");
form.querySelector(`input[name="hoge"]`).value = "hoge";
const data = new FormData(form);

fetch("...", {
    "credentials":"include",
    "headers":{
        "accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
        "accept-language":"ja-JP,ja;q=0.9,en-US;q=0.8,en;q=0.7",
        "cache-control":"max-age=0",
        "content-type":"application/x-www-form-urlencoded",
        "upgrade-insecure-requests":"1"
    },
    "body": data,
    "method":"POST",
    "mode":"cors"
}).then(res => res.text()).then(body => {
   // はい
})

FormData オブジェクトの利用 - ウェブデベロッパーガイド | MDN
FormData - Web API | MDN

Youtube Music使い始めて使うのをやめた

Spotifyを課金して使っていたけど、Youtube Musicを使ってみようと思って使い始めた。が、結局Spotifyに戻った。apple musicも課金してるけど、Android版の出来があんまよくなくてアプリが落ちたりするので最近あんま使ってない。

歌詞の表示がない

あるのかもしれないけど、どこにあるのかわからなかった。見ることがないので別になくてもいいけど。

動画を見ない

仕事中に聞くことが多いし、通勤時間も徒歩を除くと3分くらいなので見ることがない。

Google Home mini等との連携が微妙

家に帰ってきて「OK Google, 音楽かけて」というとSpotifyと連携している場合はスマホで流していた曲が流れる(気がする)
Youtube musicは連動せず違う曲が流れる。またSpotifyはPCからChromecast経由で流せるけど、Youtube musicは流せない。
Google Play musicだとまたちょっと違うかも。

MVを音源にしていることがある

MVを音源にしている曲がある。動画を見ていないのに突然話し始められるとびっくりする。星野源とか。
たぶん、他のサブスクリプションでは曲自体がないので便利に感じる人もいそう。例えば花譜 - YouTubeとか聞けるのは便利

まとめ

曲数とかは特に気にならなかった。曲のサジェストも特に不便を感じることはなかった。ただapple musicのFriends mixとかは面白いのでそういう面白さはなかった。
またYoutube Premiumで登録したので、Youtubeの広告が表示されなくなったのは想像以上によかった。なので、結局課金はしてる。