예제 #1
0
 def test_verbose_description(self):
     matchee = 2
     matcher = Equals(3)
     mismatch = matcher.match(2)
     e = MismatchError(matchee, matcher, mismatch, True)
     expected = (
         "Match failed. Matchee: %r\n"
         "Matcher: %s\n"
         "Difference: %s\n" % (matchee, matcher, matcher.match(matchee).describe())
     )
     self.assertEqual(expected, str(e))
예제 #2
0
 def test_verbose_description(self):
     matchee = 2
     matcher = Equals(3)
     mismatch = matcher.match(2)
     e = MismatchError(matchee, matcher, mismatch, True)
     expected = ('Match failed. Matchee: %r\n'
                 'Matcher: %s\n'
                 'Difference: %s\n' % (
                     matchee,
                     matcher,
                     matcher.match(matchee).describe(),
                 ))
     self.assertEqual(expected, str(e))
예제 #3
0
class FileContains(Matcher):
    """Matches if the given file has the specified contents.

    This differs from testtools' matcher in that it is strict about binary and
    text; a comparison of text must be done with an encoding.
    """
    def __init__(self, contents=None, matcher=None, encoding=None):
        """Construct a ``FileContains`` matcher.

        Can be used in a basic mode where the file contents are compared for
        equality against the expected file contents (by passing ``contents``).
        Can also be used in a more advanced way where the file contents are
        matched against an arbitrary matcher (by passing ``matcher`` instead).

        :param contents: If specified, match the contents of the file with
            these contents.
        :param matcher: If specified, match the contents of the file against
            this matcher.
        :param encoding: If specified, the file is read in text mode with the
            given encoding; ``contents`` should be a Unicode string, or
            ``matcher`` should expect to compare against one. If ``encoding``
            is not specified or is ``None``, the comparison is done byte-wise;
            ``contents`` should be a byte string, or ``matcher`` should expect
            to compare against one.
        """
        if contents is None and matcher is None:
            raise AssertionError(
                "Must provide one of `contents` or `matcher`.")
        if contents is not None and matcher is not None:
            raise AssertionError(
                "Must provide either `contents` or `matcher`, not both.")
        if matcher is None:
            self.matcher = Equals(contents)
        else:
            self.matcher = matcher
        self.encoding = encoding

    def match(self, path):
        mismatch = PathExists().match(path)
        if mismatch is not None:
            return mismatch
        if self.encoding is None:
            # Binary match.
            with open(path, "rb") as fd:
                actual_contents = fd.read()
        else:
            # Text/Unicode match.
            with open(path, "r", encoding=self.encoding) as fd:
                actual_contents = fd.read()
        return self.matcher.match(actual_contents)

    def __str__(self):
        if self.encoding is None:
            return ("File at path exists and its contents (unencoded; raw) "
                    "match %s" % (self.matcher, ))
        else:
            return ("File at path exists and its contents (encoded as %s) "
                    "match %s" % (self.encoding, self.matcher))
예제 #4
0
 def test_assertThat_verbose_output(self):
     matchee = "foo"
     matcher = Equals("bar")
     expected = (
         "Match failed. Matchee: %r\n"
         "Matcher: %s\n"
         "Difference: %s\n" % (matchee, matcher, matcher.match(matchee).describe())
     )
     self.assertFails(expected, self.assertThat, matchee, matcher, verbose=True)
예제 #5
0
 def test_assertThat_verbose_output(self):
     matchee = 'foo'
     matcher = Equals('bar')
     expected = (
         'Match failed. Matchee: %r\n'
         'Matcher: %s\n'
         'Difference: %s\n' % (
             matchee,
             matcher,
             matcher.match(matchee).describe(),
             ))
     self.assertFails(
         expected, self.assertThat, matchee, matcher, verbose=True)
예제 #6
0
 def test_assertThat_verbose_output(self):
     matchee = 'foo'
     matcher = Equals('bar')
     expected = (
         'Match failed. Matchee: %r\n'
         'Matcher: %s\n'
         'Difference: %s\n' % (
             matchee,
             matcher,
             matcher.match(matchee).describe(),
             ))
     self.assertFails(
         expected, self.assertThat, matchee, matcher, verbose=True)
예제 #7
0
 def test_file_exists_content_mismatch(self, observed, expected):
     """
     If the file exists, the content is matched against the given matcher.
     If it mismatches, the message includes both the filename and the
     message from the underlying matcher.
     """
     assume(observed != expected)
     matcher = Equals(expected)
     path = self.make_temporary_path()
     path.setContent(observed)
     mismatch = file_contents(matcher).match(path)
     self.assertThat(
         mismatch.describe(),
         Equals('%s has unexpected contents:\n%s' %
                (path.path, matcher.match(observed).describe())))
예제 #8
0
 def test_verbose_unicode(self):
     # When assertThat is given matchees or matchers that contain non-ASCII
     # unicode strings, we can still provide a meaningful error.
     matchee = '\xa7'
     matcher = Equals('a')
     mismatch = matcher.match(matchee)
     expected = ('Match failed. Matchee: %s\n'
                 'Matcher: %s\n'
                 'Difference: %s\n' % (
                     text_repr(matchee),
                     matcher,
                     mismatch.describe(),
                 ))
     e = MismatchError(matchee, matcher, mismatch, True)
     self.assertEqual(expected, str(e))
예제 #9
0
 def test_file_exists_content_mismatch(self, observed, expected):
     """
     If the file exists, the content is matched against the given matcher.
     If it mismatches, the message includes both the filename and the
     message from the underlying matcher.
     """
     assume(observed != expected)
     matcher = Equals(expected)
     path = self.make_temporary_path()
     path.setContent(observed)
     mismatch = file_contents(matcher).match(path)
     self.assertThat(
         mismatch.describe(),
         Equals(
             '%s has unexpected contents:\n%s' %
             (path.path, matcher.match(observed).describe())))
예제 #10
0
 def test_assertThat_verbose_unicode(self):
     # When assertThat is given matchees or matchers that contain non-ASCII
     # unicode strings, we can still provide a meaningful error.
     matchee = _u('\xa7')
     matcher = Equals(_u('a'))
     expected = (
         'Match failed. Matchee: %s\n'
         'Matcher: %s\n'
         'Difference: %s\n\n' % (
             repr(matchee).replace("\\xa7", matchee),
             matcher,
             matcher.match(matchee).describe(),
             ))
     e = self.assertRaises(
         self.failureException, self.assertThat, matchee, matcher,
         verbose=True)
     self.assertEqual(expected, self.get_error_string(e))
예제 #11
0
 def test_assertThat_verbose_unicode(self):
     # When assertThat is given matchees or matchers that contain non-ASCII
     # unicode strings, we can still provide a meaningful error.
     matchee = _u('\xa7')
     matcher = Equals(_u('a'))
     expected = (
         'Match failed. Matchee: %s\n'
         'Matcher: %s\n'
         'Difference: %s\n\n' % (
             repr(matchee).replace("\\xa7", matchee),
             matcher,
             matcher.match(matchee).describe(),
             ))
     e = self.assertRaises(
         self.failureException, self.assertThat, matchee, matcher,
         verbose=True)
     self.assertEqual(expected, self.get_error_string(e))
예제 #12
0
 def test_verbose_unicode(self):
     # When assertThat is given matchees or matchers that contain non-ASCII
     # unicode strings, we can still provide a meaningful error.
     matchee = _u("\xa7")
     matcher = Equals(_u("a"))
     mismatch = matcher.match(matchee)
     expected = (
         "Match failed. Matchee: %s\n"
         "Matcher: %s\n"
         "Difference: %s\n" % (text_repr(matchee), matcher, mismatch.describe())
     )
     e = MismatchError(matchee, matcher, mismatch, True)
     if str_is_unicode:
         actual = str(e)
     else:
         actual = unicode(e)
         # Using str() should still work, and return ascii only
         self.assertEqual(expected.replace(matchee, matchee.encode("unicode-escape")), str(e).decode("ascii"))
     self.assertEqual(expected, actual)
예제 #13
0
class IsResponse(Matcher):

    def __init__(self, expected_content, expected_code=200, decode=None):
        """Construct a new IsResponse matcher.

        :param expected_content: The content you want to match against the
            response body. This can either be a matcher, a string, or a
            bytestring.

        :param expected_code: Tht HTTP status code you want to match against.

        :param decode: Whether to decode the response data according to the
            response charset. This can either be set implicitly or explicitly.
            If the 'expected_content' parameter is a string, this will
            implicitly be set to True. If 'expected_content' is a bytestring,
            this will be set to False. If 'expected_content' is a matcher,
            this will be set to True. Setting this parameter to a value
            explicitly disables this implicit behavior.
        """
        if isinstance(expected_content, str):
            self._decode = True
            expected_content = Equals(expected_content)
        elif isinstance(expected_content, bytes):
            self._decode = False
            expected_content = Equals(expected_content)
        else:
            self._decode = decode or True
        self.expected_content = expected_content
        self.expected_code = Equals(expected_code)

    def match(self, response):
        mismatch = self.expected_code.match(response.status_code)
        if mismatch:
            return mismatch
        data = response.data
        if self._decode:
            data = data.decode(response.charset)
        return self.expected_content.match(data)

    def __str__(self):
        return "IsResponse(%r, %r)" % (
            self.expected_content, self.expected_code)
예제 #14
0
 def test_verbose_unicode(self):
     # When assertThat is given matchees or matchers that contain non-ASCII
     # unicode strings, we can still provide a meaningful error.
     matchee = _u('\xa7')
     matcher = Equals(_u('a'))
     mismatch = matcher.match(matchee)
     expected = ('Match failed. Matchee: %s\n'
                 'Matcher: %s\n'
                 'Difference: %s\n' % (
                     text_repr(matchee),
                     matcher,
                     mismatch.describe(),
                 ))
     e = MismatchError(matchee, matcher, mismatch, True)
     if str_is_unicode:
         actual = str(e)
     else:
         actual = unicode(e)
         # Using str() should still work, and return ascii only
         self.assertEqual(
             expected.replace(matchee, matchee.encode("unicode-escape")),
             str(e).decode("ascii"))
     self.assertEqual(expected, actual)
예제 #15
0
 def test_assertThat_output(self):
     matchee = 'foo'
     matcher = Equals('bar')
     expected = matcher.match(matchee).describe()
     self.assertFails(expected, self.assertThat, matchee, matcher)
예제 #16
0
 def test_default_description_unicode(self):
     matchee = '\xa7'
     matcher = Equals('a')
     mismatch = matcher.match(matchee)
     e = MismatchError(matchee, matcher, mismatch)
     self.assertEqual(mismatch.describe(), str(e))
예제 #17
0
 def test_assertThat_output(self):
     matchee = 'foo'
     matcher = Equals('bar')
     expected = matcher.match(matchee).describe()
     self.assertFails(expected, self.assert_that_callable, matchee, matcher)
예제 #18
0
 def test_default_description_unicode(self):
     matchee = _u('\xa7')
     matcher = Equals(_u('a'))
     mismatch = matcher.match(matchee)
     e = MismatchError(matchee, matcher, mismatch)
     self.assertEqual(mismatch.describe(), str(e))
예제 #19
0
    def wait_for(self, expected_value, timeout=10):
        """Wait up to 10 seconds for our value to change to
        *expected_value*.

        *expected_value* can be a testtools.matcher. Matcher subclass (like
        LessThan, for example), or an ordinary value.

        This works by refreshing the value using repeated dbus calls.

        :raises AssertionError: if the attribute was not equal to the
         expected value after 10 seconds.

        :raises RuntimeError: if the attribute you called this on was not
         constructed as part of an object.

        """
        # It's guaranteed that our value is up to date, since __getattr__
        # calls refresh_state. This if statement stops us waiting if the
        # value is already what we expect:
        if self == expected_value:
            return

        if self.name is None or self.parent is None:
            raise RuntimeError(
                "This variable was not constructed as part of "
                "an object. The wait_for method cannot be used.")

        def make_unicode(value):
            if isinstance(value, bytes):
                return value.decode('utf8')
            return value

        if hasattr(expected_value, 'expected'):
            expected_value.expected = make_unicode(expected_value.expected)

        # unfortunately not all testtools matchers derive from the Matcher
        # class, so we can't use issubclass, isinstance for this:
        match_fun = getattr(expected_value, 'match', None)
        is_matcher = match_fun and callable(match_fun)
        if not is_matcher:
            expected_value = Equals(expected_value)

        time_left = timeout
        while True:
            # TODO: These next three lines are duplicated from the parent...
            # can we just have this code once somewhere?
            _, new_state = self.parent._get_new_state()
            new_state = translate_state_keys(new_state)
            new_value = new_state[self.name][1:]
            if len(new_value) == 1:
                new_value = make_unicode(new_value[0])
            # Support for testtools.matcher classes:
            mismatch = expected_value.match(new_value)
            if mismatch:
                failure_msg = mismatch.describe()
            else:
                self.parent._set_properties(new_state)
                return

            if time_left >= 1:
                sleep(1)
                time_left -= 1
            else:
                sleep(time_left)
                break

        raise AssertionError(
            "After %.1f seconds test on %s.%s failed: %s" %
            (timeout, self.parent.__class__.__name__, self.name, failure_msg))