Motomichi Works Blog

モトミチワークスブログです。その日学習したことについて書いている日記みたいなものです。

何ミリ秒か待ってからテストする | Vuex + vue-test-utils その0005

はじめに

Vue.nextTick()を使ってDOMを更新して解決できるようなことは、Vue.nextTick()を使うのが良いと思います。

実装上setTimeout()を使っている箇所があったので、テストコードでも100ミリ秒待ってから実行するなどしました。

Vue.nextTick()で非同期に更新されるDOMのテストについては以下の記事に書きました。

stateの更新に伴うDOMの更新を待ってからテストする(非同期処理で更新されるstateのテスト) | Vuex + vue-test-utils その0004 - Motomichi Works Blog

wait_millisecond.jsの作成とその記述内容

wait_millisecond.jsを作成して以下の通り記述しました。

export default async function waitMillisecond (num) {
  function wait (num) {
    return new Promise((resolve) => {
      setTimeout(() => {
        resolve('resolved');
      }, num);
    });
  };

  const message = await wait(num);
  return message;
};

hoge.spec.jsの作成とその記述内容

import waitMillisecond from '@/path/to/wait_millisecond.js';

〜略〜

describe('サンプル', () => {
  it('サンプル', async () => {
    〜略〜

    // 100ミリ秒待つ
    await waitMillisecond(100).then((message) => {
      // resolved
      console.log(message);
    });

    // テストする
    expect(example).toBe('hoge');
  });
});

stateの更新に伴うDOMの更新を待ってからテストする(非同期処理で更新されるstateのテスト) | Vuex + vue-test-utils その0004

参考にさせていただいたページ

vue-test-utils公式(英語)

vue-test-utils公式(日本語)

Vue.nextTick()について Vue.js公式 (v2.x)

awaitについて

サンプルコード

サンプルとしては、上記した公式ドキュメントを確認していただくのが確実だと思います。

DOMの更新を待ってテストを実行するにはVue.nextTick()を使う。またはVue.nextTick()にasync awaitも組み合わせて使うということになります。

特に はじめる | Vue Test Utils非同期動作のテスト | Vue Test Utils を見るのが良いと思います。

await nextTick()の処理完了を1度待つ

以下のコードはhoge.spec.jsの一部を抜粋したものと考えてください。

// async functionキーワードで関数を定義します。
async function getHoge() {
  const button = wrapper.find('.button');
  button.trigger('click');

  // await演算子でVue.nextTickに渡したコールバック処理の完了を待ちます。
  await Vue.nextTick(() => {
    console.log('DOM updated');
  });

  // ここから下はawait演算子をつけたVue.nextTick()のコールバック処理が完了してから実行されます。
  console.log('find DOM');
  const hoge = wrapper.find('.hoge');
  return hoge;
}

describe('サンプル', () => {
  it('サンプル', () => {
    // Promiseを返す関数の戻り値は必ずreturnしてください。returnしないとテスト結果判定ができず、全て成功扱いになってしまいます。
    return getHoge().then((hoge) => {
      // hogeをテストします。
    })
  });
});

await nextTick()の処理完了を2度待つ

テスト対象が表示されるまでに複数回DOMの更新をしたいときがあると思います。
そんなときのためのサンプルです。

以下のコードはhoge.spec.jsの一部を抜粋したものと考えてください。

// async functionキーワードで関数を定義します。
async function getHoge() {
  const button = wrapper.find('.button');
  button.trigger('click');

  // await演算子でVue.nextTickに渡したコールバック処理の完了を待ちます。
  await Vue.nextTick(() => {
    console.log('DOM updated');
  });

  // ここから下はawait演算子をつけたVue.nextTick()のコールバック処理が完了してから実行されます。
  console.log('1度待った');



  // もう一度await演算子でVue.nextTickに渡したコールバック処理の完了を待ちます。
  await Vue.nextTick(() => {
    console.log('DOM updated');
  });

  // ここから下はawait演算子をつけたVue.nextTick()のコールバック処理が完了してから実行されます。
  console.log('2度待った');

  console.log('find DOM');
  const hoge = wrapper.find('.hoge');
  return hoge;
}

describe('サンプル', () => {
  it('サンプル', () => {
    // Promiseを返す関数の戻り値は必ずreturnしてください。returnしないとテスト結果判定ができず、全て成功扱いになってしまいます。
    return getHoge().then((hoge) => {
      // hogeをテストします。
    })
  });
});

rails sしたらYour Yarn packages are out of date!と表示された

問題のメッセージ

rails s したら以下のようなメッセージが表示されて、rails server起動できませんでした。

========================================
  Your Yarn packages are out of date!
  Please run `yarn install --check-files` to update.
========================================


To disable this check, please change `check_yarn_integrity`
to `false` in your webpacker config file (config/webpacker.yml).


yarn check v1.7.0
success Folder in sync.
Done in 0.14s.
yarn check v1.7.0
error "@babel/core#@babel/helpers" is wrong version: expected "^7.9.0", got "7.5.5"
error "@babel/core#@babel/template" is wrong version: expected "^7.8.6", got "7.4.4"
error "@babel/core#@babel/helper-module-transforms#@babel/helper-replace-supers" is wrong version: expected "^7.8.6", got "7.5.5"
error "@babel/preset-env#@babel/plugin-transform-classes#@babel/helper-define-map" is wrong version: expected "^7.8.3", got "7.5.5"
error "@babel/preset-env#@babel/plugin-transform-object-super#@babel/helper-replace-supers" is wrong version: expected "^7.8.3", got "7.5.5"
error "@babel/core#@babel/helper-module-transforms#@babel/helper-simple-access#@babel/template" is wrong version: expected "^7.8.3", got "7.4.4"
error "babel-jest#babel-plugin-istanbul#istanbul-lib-instrument#@babel/template" is wrong version: expected "^7.7.4", got "7.4.4"
error Found 7 errors.
info Visit https://yarnpkg.com/en/docs/cli/check for documentation about this command.

書いてある通りやってみるが失敗

Please run yarn install --check-files to update. と書いてあるので

yarn install --check-files

を実行してから

rails s

をもう一度してみましたがだめでした。

解決した

一度 node_modulesディレクトリとyarn.lockファイルを削除します。

rm -rf node_modules/
rm yarn.lock

yarn installし直します。

yarn install

rails sしたら無事に起動できました。

rails s

依存パッケージとして深い階層にもともとあったものを、devDependenciesとかdependenciesに追加するとyarn.lockに定義されたバージョンと齟齬が出てエラーになるような感じなのかな?

JavaScript学習日記 その0007 文字列の中に半角文字が混ざっているか判定する

参考にさせて頂いたページ

半角かどうかの判定について

半角カナかどうかの判定について

第一水準漢字と第二水準漢字について

JIS文字コード表について

http://charset.7jp.net/sjis.html

サンプルコード

const hankakuChars = [];
let value = event.target.value;

// 改行を削除
value = value.replace(/\r?\n/g, '');

for (let i = 0; i < value.length; i++) {
  // 1文字ずつ16進数文字コードに変換
  const charCode = value.charCodeAt(i);

  // 半角文字に該当するか16進数で比較
  const isHankaku = (charCode >= 0x0 && charCode < 0x81) ||
    charCode === 0xf8f0 ||
    (charCode >= 0xff61 && charCode < 0xffa0) ||
    (charCode >= 0xf8f1 && charCode < 0xf8f4);

  if (isHankaku) {
    hankakuChars.push(value[i]);
  }
}

if (hankakuChars.length === 0) {
  console.log('半角文字はありません。');
} else {
  console.log(hankakuChars);
}

おまけ

UnicodeUTF-8文字集合(文字セット)と文字符号化方式」について

Log in with Atlassian account

0xから始まる数について

0xから始まる数は16進数です。

半角カナかどうか判定する

半角カナかどうかは「Unicode 内のそれぞれの文字種の範囲 - みちのぶのねぐら 工作室 旧館」によると

半角カナなどは、 0xFF61 - 0xFF9F になります。

とのことです。

Unicode一覧 0000-0FFF - Wikipedia などで、 を検索して確認するとよさそうです。

ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙゚

第一水準漢字と第二水準漢字かどうか判定する

[JavaScript] 全角文字のJIS第一水準、第二水準などをチェックしたい。あとencoding.js « きんくまデザイン によると、JavaScriptの場合は文字を列挙していくか、ライブラリ使うしかなさそうな感じです。

JIS文字コードと句と点について

JIS文字コード表: http://charset.7jp.net/sjis.html

句と点について: たとえば「&H889F」は、JISでは&Hは16進数であること、88の部分が点、9Fの部分が句を表しています。10進数で表現する場合は句、点はまた違います。

JavaScript学習日記 その0006 文字列から改行を削除する

サンプル

textareaタグに複数行の文字列が入力された場合などに以下のようにします。

let str = event.target.value;
str = str.replace(/\r?\n/g, '');

Visual Studio Code バージョン1.65.2の検索フィールドを下部に移動する(Visual Studio Codeの設定変更)

参考にさせていただいたページ

バージョン1.65.2以降の場合

どのバージョンからなのかわかりませんが、ドラッグすると移動できます。

  • まずメニューから「View > Debug Console」とか「View > Termial」を選択して、下部のツールを表示させます。
  • サイドバーに表示されている検索アイコンをドラッグして、「PROBLEMS | OUTPUT | DEBUG CONSOLE | TERMINAL」と表示されているところに移動します。

旧バージョンの場合

旧バージョンでは、settings.jsonに記述して変更していました。

settings.jsonを開く

メニューから開く

  • 上部のメニューから「Code > Preferences > Settings」を選択してSettingsを開きます。
  • 右上のファイルアイコンをクリックすると、settings.jsonが開きます。

直接探すことは無いと思いますが、格納先

お使いの環境によって格納先が異なります。

  • Windows: %APPDATA%\Code\User\settings.json (C:\Users\ユーザー名\AppData\Roaming\Code\User\settings.json
  • Mac: $HOME/Library/Application Support/Code/User/settings.json
  • Linux: $HOME/.config/Code/User/settings.json

settings.jsonを編集する

以下のように記述すると検索フィールドは下部に移動できます。

"search.location": "panel",

以下のようにすると検索フィールドは左に移動できます。

"search.location": "left",

settings.jsonサンプル その1

{
    "window.zoomLevel": 0,
    "editor.fontFamily": "Ricty Diminished",
    "editor.tabSize": 2,
    "editor.renderWhitespace": "all",
    "editor.wordWrap": "on",
    "editor.fontSize": 16,
    "emmet.includeLanguages": {
        "erb": "html",
    },
    "workbench.editor.labelFormat": "short",
    "javascript.updateImportsOnFileMove.enabled": "always"
}

settings.jsonサンプル その2

{
  "window.zoomLevel": 0,
  "editor.fontFamily": "Cica",
  "editor.tabSize": 2,
  "editor.renderWhitespace": "all",
  "editor.wordWrap": "on",
  "editor.fontSize": 16,
  "emmet.includeLanguages": {
    "erb": "html"
  },
  "workbench.editor.labelFormat": "short",
  "javascript.updateImportsOnFileMove.enabled": "always",
  "typescript.updateImportsOnFileMove.enabled": "always",
  "css.validate": false,
  "less.validate": false,
  "scss.validate": false,
  // ESLintに対応しているファイルは保存時にESLintによるフォーマットを行う
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true,
    "source.fixAll.stylelint": true
  },
  "editor.formatOnSave": false,
  "eslint.packageManager": "yarn",
  "typescript.enablePromptUseWorkspaceTsdk": true,
  "typescript.tsdk": "./node_modules/typescript/lib",
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "[graphql]": {
    "editor.formatOnSave": true
  },
  "[javascript]": {
    "editor.formatOnSave": true
  },
  "[javascriptreact]": {
    "editor.formatOnSave": true
  },
  "[json]": {
    "editor.formatOnSave": true
  },
  "[typescript]": {
    "editor.formatOnSave": true
  },
  "[typescriptreact]": {
    "editor.formatOnSave": true
  }
}

webpack4.x + sass-loader + postcss-loader + autoprefixerでscssファイルをコンパイルする

今日の環境

  • Windows10 Home
  • node 12.13.1
  • npm 6.13.1
  • webpack 4.41.2
  • webpack-cli 3.2.3

プロジェクトディレクトリを作成

mkdir webpack_4_scss_introduction
cd webpack_4_scss_introduction

npm initする

npm init

グローバルにインストール

npm install -g webpack webpack-cli

プロジェクトにインストール

npm install -D webpack webpack-cli
npm install -D webpack-import-glob-loader
npm install -D style-loader css-loader sass-loader node-sass postcss-loader autoprefixer
npm install -D mini-css-extract-plugin

ディレクトリとファイルを作成

mkdir src\scss\modules
copy nul src\scss\style.scss
copy nul src\scss\modules\_mod_example.scss
copy nul webpack.config.js

webpack.config.jsの編集

以下の通り記述

const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
  entry: {
    style: './src/scss/style.scss',
  },
  output: {
    path: `${__dirname}/dist`,
  },
  module: {
    rules: [
      {
        test: /\.scss$/,
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
          },
          {
            loader: 'css-loader',
            options: {
              // CSS内のurl()メソッドの取り込みを禁止する
              url: false,
              // ソースマップの利用有無
              sourceMap: true,
              // Sass+PostCSSの場合は2を指定
              importLoaders: 2
            },
          },
          {
            loader: 'postcss-loader',
            options: {
                // PostCSS側でもソースマップを有効にする
                sourceMap: true,
                plugins: [
                  // Autoprefixerを有効化
                  // ベンダープレフィックスを自動付与する
                  require('autoprefixer')({ grid: true })
                ]
            },
          },
          {
            loader: 'sass-loader',
          },
          {
            loader: 'webpack-import-glob-loader',
          },
        ],
      }
    ],
  },
  plugins:[
    // cssの出力先を指定する
    new MiniCssExtractPlugin({ filename: 'style/[name].css' }),
  ],
}

src/scss/style.scssの編集

webpack-import-glob-loaderをインストールしているのでglobパターンが使用できます。

@import "./modules/*";

src/scss/modules/_mod_example.scssの編集

autoprefixerが上手く機能しているか試す為に::placeholderを記述してみます。

/*
  残るコメント
*/
// 残らないコメント
.mod-example {
  .mod-example__hoge {
    background-image: url(../images/example.png);
  }
  ::placeholder {
    color: #aaaaaa;
  }
}

ビルドしてみる

webpack --mode=development
webpack --mode=development --watch

生成されたstyle.cssを確認する

ベンダープレフィックスが付いているのが確認できました。