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 未必能給你摸到最好的答案,但它給你改變心意的機會。