文章

Time picker key suggestion

前陣子遇到 UI 上有要求做個 Time picker 有以下要求:

這個要求要處理很多特殊 cases,如:

  • 2 –> 可以是 23:50 或 2:59 –> 可按 0-5
  • 15 –> 可以是 1:39 或 13:59 –> 可按 0-9
  • 16 –> 可以是 16:59 –> 可按 0-5

如果再加可設定最大最小就更麻煩。

起初的想法是先用 regexp 先對好時間格式,然後才處理可按甚麼的問題。@angusdev 做的這個 sample 就用這個方法,不過就未有最大最小的限制。

我想不到很好的寫法,就讓 unit test 去 drive,寫 jasmine test case:

var testData = [
    {input:'', min:'', max:'', expect:[0,9]},
    //...
];
testData.forEach(function(d){
    it("should expect time input:"+d.input+
         " min:"+d.min+" max:"+d.max+
         " to have "+d.expect.toString()+"", 
    function(){
        expect($scope.expectTimeKeys(d.input, d.min, d.max))
            .toEqual(d.expect);
    });
});

(我在用 angular 所以見到 $scope, 不過沒差啦..)

在一路加入 test case 的情況下,我漸漸寫出了一些類似計算數字進位的東西,有點像樣了 (見這plunker)。可是到了後期,越加 test case 卻變得越難改動,程式有點彊化。

我想像到日後如果發現有 bug 我可能很難才找到問題所在,所以決定砍掉重練好了。新的想法是先用暴力發窮舉所有可能性,再在當中 filter 好了。因為已發展了一堆 test case 出來,就整個 test case 抄出來,重新寫過。結果是這個 plunker。用暴力法的好處是比較易明,但會有效能考慮,我自己測試下在當代 browser 強勁的 js 執行力下,其實也足夠快了。

當中教訓是:TDD 未必能給你摸到最好的答案,但它給你改變心意的機會。

回應

  1. 如果要自動 pad-zero
    1 -> 0001
    12 -> 0012
    123 -> 0123
    1234 -> 1234

    根本一開始無可能知道係第幾個 digit 去 limit, 除非再加上自動唔 pad-limit;
    e.g. "2" can be
    12 -> 0012 (0-9)
    123 -> 0123 (0-5)
    1234 -> 1234 (0-9)
    depends which digit it should be

    @angusdev 做的個 sample 由 "中間" 開始 input 會好奇怪 (e.g. 1 vs 01)

*