かもメモ

自分の落ちた落とし穴に何度も落ちる人のメモ帳

JavaScript ファイル名 (文字列) から拡張子を取得したい

拡張子を含むファイル名の文字列から、拡張子とか拡張子を除いたファイル名を取得する方法のメモ

拡張子の始まりの位置を特定すれば拡張子とファイル名に分解できる

拡張子とは何かを考える

  • 拡張子は . から始まる
  • 文字列の一番最後に出現する . 以降が拡張子
  • 文字列の一番最後に出現する . 以前がファイル名

文字列に含まれる最後の . の位置を取得して、その前後で分解する

// 文字列中の最後の `.` の位置を取得
const extensionIndex = fileNameStr.lastIndexOf('.');
const hasExtension = extensionIndex > 0 && extensionIndex < fileNameStr.length - 1;
// `.` 以降が拡張子
const extension = hasExtension ? fileNameStr.substr(extensionIndex) | undefined;
// '.' 以前がファイル名
const fileName =  hasExtension ? fileNameStr.substr(0, extensionIndex) : fileNameStr;
  • 文字列中に . が存在しない場合は、拡張子なし・全てファイル名と判断する
  • 最後の . が文字列の先頭にある場合は、拡張子なし・全てファイル名と判断する
  • 最後の . が文字列の最後にある場合は、拡張子なし・全てファイル名と判断する

Sample

See the Pen Untitled by KIKIKI (@kikiki_kiki) on CodePen.

? パラメーターが存在する場合、パラメーターと拡張子とファイル名に分解してみるサンプル

厳格にはダメかもだけど、入力値が絞れるような場合はこんな感じで拡張子とファイル名とが取得できそう


[参考]

TypeScript JEST 引数を取る関数のエラーになる場合のテストにハマったメモ

3億年ぶりに JEST を使って引数を取る関数がエラーになる場合のテストケースを書いていてちょいハマったのでメモ

環境
  • jest ^27.5.0
  • ts-jest ^27.1.3
  • typescript ^4.5.5

JEST toThrow(error) でエラーになる場合のテストができる

toThrow() に取れる

  • 正規表現: エラーメッセージがパターンに マッチする か検証します
  • 文字列:エラーメッセージが文字列を含む か検証します
  • error オブジェクト: エラーメッセージがオブジェクトのmessageプロパティと等しいかを検証します
  • errorクラス: errorオブジェクトがそのクラスのインスタンスであるかを検証します

.toThrowError(error?)toThrow(error)エイリアス

function drinkFlavor(flavor) {
  if (flavor == 'octopus') {
    throw new DisgustingFlavorError('yuck, octopus flavor');
  }
}

// test
test('throws on octopus', () => {
  function drinkOctopus() {
    drinkFlavor('octopus');
  }

  // Test that the error message says "yuck" somewhere: these are equivalent
  expect(drinkOctopus).toThrowError(/yuck/);
  expect(drinkOctopus).toThrowError('yuck');

  // Test the exact error message
  expect(drinkOctopus).toThrowError(/^yuck, octopus flavor$/);
  expect(drinkOctopus).toThrowError(new Error('yuck, octopus flavor'));

  // Test that we get a DisgustingFlavorError
  expect(drinkOctopus).toThrowError(DisgustingFlavorError);
});

cf. .toThrow(error?) | Expect · Jest

テストする関数は expect 内で実行される必要がある

引数を取る関数のエラーになる場合のテストをしようと下記のように書いて正しくエラーを取ることができなかった。

const myFunc = (data: string[]) => {
  if (!data.length) {
    throw new Error('Empty data :(');
  }
};

// test
describe('myFunc', () => {
  test('When argument is an empty array, throw error', () => {
    expect(myFunc([])).toThrow();
  });
});

👇 テストを実行

$ npx jest
 FAIL  ./myFunc.test.ts
  myFunc
    ✕ When argument is an empty array, throw error (1 ms)
  ● myFunc › When argument is an empty array, throw error
    Empty data :(
      1 | const myFunc = (data: string[]) => {
      2 |   if (!data.length) {
    > 3 |     throw new Error('Empty data :(');
        |           ^
      4 |   }
      5 | };

エラーが発生している箇所でテストがエラーになっている?

テストしたい関数が先に実行されてしまっているのが原因

エラーの発生は関数が返す値ではないので、expect(myFunc([])) という書き方だと、先に関数が実行されエラーが発生してしまうので expect でエラーをキャッチすることができずテストが落ちてしまっていた。

エラーが発生することのテストはテストする関数を別途関数でラップする必要がある

expect に関数を渡すと実行されるので、エラーの発生する関数を別の関数で囲ってあげれば良い

// test
describe('myFunc', () => {
  test('When argument is an empty array, throw error', () => {
-   expect(myFunc([])).toThrow();
+   expect(() => myFunc([])).toThrow();
  });
});

👇 テストを実行

$ npx jest
 PASS  ./myFunc.test.ts
  myFunc
    ✓ When argument is an empty array, throw error (9 ms)

₍ ᐢ. ̫ .ᐢ ₎ 👌

よくみたら公式のサンプルもテスト用に関数で囲ってた。
教訓。公式のコードはちゃんと見よう。
おわり。


[参考]

作業しながら空挺ドラゴンズのアニメ見返してて、改めて面白いな〜と思って原作買ったら原作の絵が超好みだった。

React TypeScript いつも使う設定のボイラーテンプレート作った

毎回 ESLint と Prettier の設定書いて、パスエイリアスの設定して、なんやかんや設定して…とメンドーなので create-react-app --template typescript ベースでゆるゆるな自分用ボイラーテンプレート作りました。

ボイラーテンプレート

やったこと

見返したらコミットログのタイポ多すぎて笑えない感じだったけど、まぁいっか…

おわり