0
1

More than 3 years have passed since last update.

宮本さんjest導入 ~オブジェクト関数からclass構文への移行~

Last updated at Posted at 2019-12-03

宮本さんjest導入の話

最初の壁

最初にjestの方に宮本さんのscriptをimport してとりあえずテスト回そうとしたら
動かないんですよね...
てか、オブジェクト関行importできまへんやん!
となりclass構文への移行を決意。

移行

とりあえずソースのせる

オブジェクト関数
loadDateUtils = function () {
  var DateUtils = {};

  // 今を返す
  var _now = new Date();
  var now = function(datetime) {
    if(typeof datetime != 'undefined') {
      _now = datetime;
    }
    return _now;
  };
  DateUtils.now = now;

  // テキストから時間を抽出
  DateUtils.parseTime = function(str) {
    str = String(str || "").toLowerCase().replace(/[A-Za-z0-9]/g, function(s) {
      return String.fromCharCode(s.charCodeAt(0) - 0xFEE0);
    });
    var reg = /((\d{1,2})\s*[:時]{1}\s*(\d{1,2})\s*(pm|)|(am|pm|午前|午後)\s*(\d{1,2})(\s*[:時]\s*(\d{1,2})|)|(\d{1,2})(\s*[:時]{1}\s*(\d{1,2})|)(am|pm)|(\d{1,2})\s*時)/;
    var matches = str.match(reg);
    if(matches) {
      var hour, min;

      // 1時20, 2:30, 3:00pm
      if(matches[2] != null) {
        hour = parseInt(matches[2], 10);
        min = parseInt((matches[3] ? matches[3] : '0'), 10);
        if(_.contains(['pm'], matches[4])) {
          hour += 12;
        }
      }

      // 午後1 午後2時30 pm3
      if(matches[5] != null) {
        hour = parseInt(matches[6], 10);
        min = parseInt((matches[8] ? matches[8] : '0'), 10);
        if(_.contains(['pm', '午後'], matches[5])) {
          hour += 12;
        }
      }

      // 1am 2:30pm
      if(matches[9] != null) {
        hour = parseInt(matches[9], 10);
        min = parseInt((matches[11] ? matches[11] : '0'), 10);
        if(_.contains(['pm'], matches[12])) {
          hour += 12;
        }
      }

      // 14時
      if(matches[13] != null) {
        hour = parseInt(matches[13], 10);
        min = 0;
      }

      return [hour, min];
    }
    return null;
  };
class構文
import { contains, isNaN } from "underscore";

export class DateUtils {
  now: Number;
  setTime(now: any) {
    return (this.now = now);
  }
  dateUtilsNow(datetime: Date) {
    let _now = new Date();
    if (typeof datetime !== "undefined") {
      _now = datetime;
    }
    return this.setTime(_now);
  }

  dateUtilsParseTime(str: any) {
    str = String(str || "")
      .toLowerCase()
      .replace(/[A-Za-z0-9]/g, (s) => {
        return String.fromCharCode(s.charCodeAt(0) - 0xfee0);
      });
    const reg = /((\d{1,2})\s*[:時]{1}\s*(\d{1,2})\s*(pm|)|(am|pm|午前|午後)\s*(\d{1,2})(\s*[:時]\s*(\d{1,2})|)|(\d{1,2})(\s*[:時]{1}\s*(\d{1,2})|)(am|pm)|(\d{1,2})\s*時)/;
    const matches = str.match(reg);
    if (matches) {
      let hour, min;

      // 1時20, 2:30, 3:00pm
      if (matches[2] != null) {
        hour = parseInt(matches[2], 10);
        min = parseInt(matches[3] ? matches[3] : "0", 10);
        if (contains(["pm"], matches[4])) {
          hour += 12;
        }
      }

      // 午後1 午後2時30 pm3
      if (matches[5] != null) {
        hour = parseInt(matches[6], 10);
        min = parseInt(matches[8] ? matches[8] : "0", 10);
        if (contains(["pm", "午後"], matches[5])) {
          hour += 12;
        }
      }

      // 1am 2:30pm
      if (matches[9] != null) {
        hour = parseInt(matches[9], 10);
        min = parseInt(matches[11] ? matches[11] : "0", 10);
        if (contains(["pm"], matches[12])) {
          hour += 12;
        }
      }

      // 14時
      if (matches[13] != null) {
        hour = parseInt(matches[13], 10);
        min = 0;
      }

      return [hour, min];
    }
    return null;
  }
}

移行方法は簡単オブジェクト関数をclassのmethodに置き換えていくだけです。
DateUtils.now = now; 時間をとってるところだったりしているとこはSetter使ったりして対応しています。

ただ、このようなSetter使用方法はESLintさんに怒られるのでconstructorに書き換える予定です。

オブジェクト関数からclass構文への移行のメリットは

  • jestにインポートできる
  • underscore.jsがimport経由で使えるので関数の前に_つけなくてすむのが地味に嬉しい

jestでtest書く

とりあえずソース抜粋

import { isEqual } from "../node_modules/underscore";
import { DateUtils } from "../_test_utils_/date_utils_test";

const dateUtils = new DateUtils();

describe("dateUtils_parseTime", () => {
  it("dateUtils_parseTime: #1", () => {
    const dateUtils_parseTime = () => {
      return isEqual([13, 1], dateUtils.dateUtilsParseTime("13:01"));
    };
    expect(dateUtils_parseTime()).toBe(true);
  });
  it("dateUtils_parseTime: #2", () => {
    const dateUtils_parseTime_test = () => {
      return isEqual([14, 2], dateUtils.dateUtilsParseTime("2:02pm"));
    };
    expect(dateUtils_parseTime_test()).toBe(true);
  });
  it("dateUtils_parseTime: #3", () => {
    const dateUtils_parseTime_test = () => {
      return isEqual([16, 3], dateUtils.dateUtilsParseTime("午後4:3"));
    };
    expect(dateUtils_parseTime_test()).toBe(true);
  });
  it("dateUtils_parseTime: #4", () => {
    const dateUtils_parseTime_test = () => {
      return isEqual([17, 0], dateUtils.dateUtilsParseTime("5pm"));
    };
    expect(dateUtils_parseTime_test()).toBe(true);
  });
  it("dateUtils_parseTime: #5", () => {
    const dateUtils_parseTime_test = () => {
      return isEqual([17, 1], dateUtils.dateUtilsParseTime("5:1pm"));
    };
    expect(dateUtils_parseTime_test()).toBe(true);
  });
  it("dateUtils_parseTime: #6", () => {
    const dateUtils_parseTime_test = () => {
      return isEqual([18, 0], dateUtils.dateUtilsParseTime("18時"));
    };
    expect(dateUtils_parseTime_test()).toBe(true);
  });
  it("dateUtils_parseTime: #7", () => {
    const dateUtils_parseTime_test = () => {
      return isEqual([19, 20], dateUtils.dateUtilsParseTime("19 : 20"));
    };
    expect(dateUtils_parseTime_test()).toBe(true);
  });
  it("dateUtils_parseTime: #8", () => {
    const dateUtils_parseTime_test = () => {
      return isEqual([20, 0], dateUtils.dateUtilsParseTime("午後8"));
    };
    expect(dateUtils_parseTime_test()).toBe(true);
  });
});

Jestの使い方

describe テストの塊
it テスト
expect テストを指定
tobo 答え指定

という感じです。

describeはdateUtils_parseTime関数のテストを使いたいのでこんな感じで

describe("dateUtils_parseTime", () => {

})

itはテスト名はよしなにこのテスト名良くないですがご容赦ください!

describe("dateUtils_parseTime", () => {
 it("dateUtils_parseTime: #1", () => {
    });
})

ここでやり方の問題ですがexpectに直接関数書いてもいいのですが
僕の好みでit内で書いてます

describe("dateUtils_parseTime", () => {
 it("dateUtils_parseTime: #1", () => {
       const dateUtils_parseTime = () => {
          return isEqual([13, 1], dateUtils.dateUtilsParseTime("13:01"));
        };
    });
})

次はexpectに先程書いた関数を記述

describe("dateUtils_parseTime", () => {
 it("dateUtils_parseTime: #1", () => {
       const dateUtils_parseTime = () => {
          return isEqual([13, 1], dateUtils.dateUtilsParseTime("13:01"));
        };
    });
     expect(dateUtils_parseTime_test())
})

最後にtoBeで結果を指定する

describe("dateUtils_parseTime", () => {
 it("dateUtils_parseTime: #1", () => {
       const dateUtils_parseTime = () => {
          return isEqual([13, 1], dateUtils.dateUtilsParseTime("13:01"));
        };
    });
     expect(dateUtils_parseTime_test()).toBe(true);
})

下記でテスト回す
npm test date_utils_test.spec

 PASS  _tests_/date_utils_test.spec.ts
  dateUtils_parseTime ←describe名
    ✓ dateUtils_parseTime: #1 (3ms)  ←it名
    ✓ dateUtils_parseTime: #2 (1ms)
    ✓ dateUtils_parseTime: #3 (1ms)
    ✓ dateUtils_parseTime: #4 (1ms)
    ✓ dateUtils_parseTime: #5
    ✓ dateUtils_parseTime: #6
    ✓ dateUtils_parseTime: #7 (1ms)
    ✓ dateUtils_parseTime: #8
  dateUtils_parseDate
    ✓ dateUtils_parseDate: #1 (1ms)
    ✓ dateUtils_parseDate: #2
    ✓ dateUtils_parseDate: #3 (1ms)

こんな感じで返ってきます。

jest導入の話はこんなところです

次はTS化の話書きます〜

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1