~lifeless/testtools/haslength

« back to all changes in this revision

Viewing changes to testtools/matchers/_higherorder.py

  • Committer: Robert Collins
  • Date: 2013-01-23 20:07:43 UTC
  • Revision ID: robertc@robertcollins.net-20130123200743-0hoe8ny6nzt32liq
* New matcher ``HasLength`` for matching the length of a collection.
  (Robert Collins)

Show diffs side-by-side

added added

removed removed

Lines of Context:
289
289
            return Mismatch(self.message % x)
290
290
 
291
291
 
292
 
def MatchesPredicateWithParams(predicate, message):
 
292
def MatchesPredicateWithParams(predicate, message, name=None):
293
293
    """Match if a given parameterised function returns True.
294
294
 
295
295
    It is reasonably common to want to make a very simple matcher based on a
308
308
    parameter. Any additional parameters supplied when constructing a matcher
309
309
    are supplied to the predicate as additional parameters when checking for a
310
310
    match.
 
311
 
 
312
    :param predicate: The predicate function.
 
313
    :param message: A format string for describing mis-matches.
 
314
    :param name: Optional replacement name for the matcher.
311
315
    """
312
316
    def construct_matcher(*args, **kwargs):
313
 
        return _MatchesPredicateWithParams(predicate, message, *args, **kwargs)
 
317
        return _MatchesPredicateWithParams(
 
318
            predicate, message, name, *args, **kwargs)
314
319
    return construct_matcher
315
320
 
316
321
 
317
322
class _MatchesPredicateWithParams(Matcher):
318
323
 
319
 
    def __init__(self, predicate, message, *args, **kwargs):
 
324
    def __init__(self, predicate, message, name, *args, **kwargs):
320
325
        """Create a ``MatchesPredicateWithParams`` matcher.
321
326
 
322
327
        :param predicate: A function that takes an object to match and
334
339
            To format a keyword arg::
335
340
 
336
341
                "{0} is not a {type_to_check}"
 
342
        :param name: What name to use for the matcher class. Pass None to use
 
343
            the default.
337
344
        """
338
345
        self.predicate = predicate
339
346
        self.message = message
 
347
        self.name = name
340
348
        self.args = args
341
349
        self.kwargs = kwargs
342
350
 
344
352
        args = [str(arg) for arg in self.args]
345
353
        kwargs = ["%s=%s" % item for item in self.kwargs.items()]
346
354
        args = ", ".join(args + kwargs)
347
 
        return 'MatchesPredicateWithParams(%r, %r)(%s)' % (
348
 
            self.predicate, self.message, args)
 
355
        if self.name is None:
 
356
            name = 'MatchesPredicateWithParams(%r, %r)' % (
 
357
                self.predicate, self.message)
 
358
        else:
 
359
            name = self.name
 
360
        return '%s(%s)' % (name, args)
349
361
 
350
362
    def match(self, x):
351
363
        if not self.predicate(x, *self.args, **self.kwargs):