On 08/16/2012 09:40 AM, Pierre-Yves Chibon wrote:
On Wed, 2012-08-15 at 14:22 +0200, tim.lauridsen(a)gmail.com wrote:
> On Wed, Aug 15, 2012 at 10:12 AM, Stanislav Ochotnicky <
> sochotnicky(a)redhat.com> wrote:
>
>> Doing this with inheritance means you have to redefine run(), because you
>> can't
>> have multiple is_applicable functions. And then would come the
>> inconsistency...in some cases it's enough to reimplement is_applicable,
>> but in
>> other cases not. You can of course create another level of inheritance (as
>> the
>> original Ruby checks do) to solve this problem
>>
>> Decorators have a different problem and that is manual tests which still
>> have
>> is_applicable. Since we got rid of it, it has to instead be changed to
>> automatic check which returns not_applicable when appropriate. Example:
>>
>> Original:
>> class CheckLocale(GenericCheckBase):
>> def __init__(self, base):
>> ...
>> self.automatic = False
>>
>> def is_applicable(self):
>> return self.has_files('/usr/share/locale/*/LC_MESSAGES/*.mo')
>>
>> New:
>> class CheckLocale(GenericCheckBase):
>> def __init__(self, base):
>> ..,
>> self.automatic = True
>>
>> def run(self):
>> if self.has_files('/usr/share/locale/*/LC_MESSAGES/*.mo'):
>> self.set_passed('inconclusive')
>> else:
>> self.set_passed('not_applicable')
>>
>
> Merging is_applicable into run and lose the is_applicable method, looks
> fine to me, the original idea, what to test if a check was applicable and
> if it was, then run the check.
> but integrating the check into run() would be good alternative too.
> The decorator way is much harder to understand if you are not python
> decorator ninja master :)
Catching up on this subject I was getting the same idea. Since the tests
can override the run() method anyway, let's just have them do that and
return 'not_applicable' when it is.
Let's have each test decide how they want to handle the is_applicable().
Imho, we should go for KISS :-)
Pierre
Seems that many people tend to think using inheritance is the most
straight-forward way. I agree on that.
I also hope and think we agree on that the default behaviour should be
defined so that manual tests (the vast majority) normally shouldn't
need to handle applicability or define run(). This also means that the
vast majority of the automatic tests could rely on the default
applicablility. I think this makes it easier both to write and read
tests (making special treatment visible).
Seems that Stan just don't like the run_if_applicable() way of
overriding. Maybe just renaming that function could make life easier?
run_when_applicable(), applicable_run(), whatever...) But keeping the
external run() interface means that the function called after checking
is_applicable needs another name...
There's another aspect: looking into Mikolaj's great proposal of a
simplifed shell interface it becomes obvious that to create simple tests
they should only declare which group they belong to (.e. g. 'Java' or
'Generic') and then only be invoked if applicable. Something like
#!/bin/bash
#@group: Java
test "something"
exit $?
But that means that the plugin handling these tests needs to use a
'is_applicable' function for every group. This is *not* part of the
Check interface, it's part of the module interface: A test module
handles a specific group, register a list of tests for it and has a
default 'is_applicable() function. Given this, it seems logical that
tests by default respect this is_applicable() function.
So, in a way, the interface function is_applicable() is resurrected. In
the check-api parlance it means that is_applicable() is part of the
AbstractRegistry interface, but not AbstractCheck.
--alec