in reply to Testing for 16 possible combinations with 4 pull-down menus

It is just a question of organizing the facts to test in a convenient way that can be tested without too much muss or fuss. The following untested validation function should do it:
# Tests the start_hour, start_minute, end_hour, and end_minute # pulldowns to verify that a consistent set of them have been # specified, and that the start time (if specified) is before # the end time. sub validate_date_pulldowns { if (defined(param('end_hour'))) { return 0 unless defined(param('start_hour')); return 0 if param('start_hour') > param('end_hour'); } if (defined(param('start_minute'))) { return 0 unless defined(param('start_hour')); } if (defined(param('end_minute'))) { return 0 unless defined(param('start_minute')); return 0 unless defined(param('end_hour')); return 0 if param('start_hour') == param('end_hour') and param('start_minute') > param('end_minute'); } return 1; }
It would be easy to extend this code sample to add in support for start/end seconds as well.

Update: Note that the key idea is my strategy of turning many combinations of conditions into a set of "guard conditions" on which you exit early. I've found that this strategy often converts deep nested decision trees into a series of fairly straightforward decisions (as above).

Replies are listed 'Best First'.
Re^2: Testing for 16 possible combinations with 4 pull-down menus
by brian_d_foy (Abbot) on Dec 11, 2004 at 05:55 UTC

    Toward this purpose I created Set::CrossProduct. Instead of figuring out all the combinations, I have a bunch of anonymous arrays that specify possible values for each input. The module handles everything and hands me one set of inputs at a time. You call them "guard conditions" and I call them "boundary conditions".

    In this case, there are only 16 combinations, but I've been able to work with thousands of combinations without making the test code huge.

    --
    brian d foy <bdfoy@cpan.org>
      Automation is good. It would have avoided the bug that I had in my code above. (If end_minute is not defined, you aren't allowed to have both start_minute and end_hour defined.)