Пример #1
0
    def test_download_datapackage(self, helpers, config,
                                  test_datapackages_path, api_client,
                                  dataset_key):
        datapackage_zip = path.join(test_datapackages_path,
                                    'the-simpsons-by-the-data.zip')
        with responses.RequestsMock() as rsps, open(datapackage_zip,
                                                    'rb') as file:
            @helpers.validate_request_headers()
            def datapackage_endpoint(_):
                return 200, {}, file.read()

            rsps.add_callback(
                rsps.GET,
                'https://download.data.world/datapackage/agentid/datasetid',
                datapackage_endpoint)

            datapackage = api_client.download_datapackage(dataset_key,
                                                          config.cache_dir)

            assert_that(datapackage, equal_to(
                path.join(config.cache_dir, 'datapackage.json')))
            assert_that(path.isfile(datapackage),
                        described_as('%0 is a file', is_(True), datapackage))

            data_subdirectory = path.join(config.cache_dir, 'data')
            assert_that(path.isdir(data_subdirectory),
                        described_as('%0 is a directory', is_(True),
                                     data_subdirectory))
            assert_that(os.listdir(config.tmp_dir),
                        described_as('%0 is empty', empty(), config.tmp_dir))
Пример #2
0
    def test_download_datapackage(self, helpers, config,
                                  test_datapackages_path, api_client,
                                  dataset_key):
        datapackage_zip = path.join(test_datapackages_path,
                                    'the-simpsons-by-the-data.zip')
        with responses.RequestsMock() as rsps, open(datapackage_zip,
                                                    'rb') as file:

            @helpers.validate_request_headers()
            def datapackage_endpoint(_):
                return 200, {}, file.read()

            rsps.add_callback(
                rsps.GET,
                'https://download.data.world/datapackage/agentid/datasetid',
                datapackage_endpoint)

            datapackage = api_client.download_datapackage(
                dataset_key, config.cache_dir)

            assert_that(
                datapackage,
                equal_to(path.join(config.cache_dir, 'datapackage.json')))
            assert_that(path.isfile(datapackage),
                        described_as('%0 is a file', is_(True), datapackage))

            data_subdirectory = path.join(config.cache_dir, 'data')
            assert_that(
                path.isdir(data_subdirectory),
                described_as('%0 is a directory', is_(True),
                             data_subdirectory))
            assert_that(os.listdir(config.tmp_dir),
                        described_as('%0 is empty', empty(), config.tmp_dir))
Пример #3
0
def has_table(table: str) -> Matcher:
    """TODO"""
    select = f"SELECT * FROM {table};"  # nosec
    return described_as(
        "DB connection has table named %0",
        given_select_returns_rows_matching(select, anything()),
        table,
    )
Пример #4
0
    def evaluate(self):
        """ Converts the current expression into a single matcher, applying
            coordination operators to operands according to their binding rules
        """

        # Apply Shunting Yard algorithm to convert the infix expression
        # into Reverse Polish Notation. Since we have a very limited
        # set of operators and binding rules, the implementation becomes
        # really simple. The expression is formed of hamcrest matcher instances
        # and operators identifiers (ints).
        ops = []
        rpn = []
        for token in self.expr:
            if isinstance(token, int):
                while len(ops) and token <= ops[-1]:
                    rpn.append(ops.pop())
                ops.append(token)
            else:
                rpn.append(token)

        # Append the remaining operators
        while len(ops):
            rpn.append(ops.pop())

        # Walk the RPN expression to create AllOf/AnyOf matchers
        stack = []
        for token in rpn:
            if isinstance(token, int):
                # Handle the NOT case in a special way since it's unary
                if token == OPERATOR.NOT:
                    stack[-1] = IsNot(stack[-1])
                    continue

                # Our operators always need two operands
                if len(stack) < 2:
                    raise RuntimeError('Unable to build a valid expression. Not enough operands available.')

                # Check what kind of matcher we need to create
                if token == OPERATOR.OR:
                    matcher = hc.any_of(*stack[-2:])
                else:  # AND, BUT
                    matcher = hc.all_of(*stack[-2:])

                stack[-2:] = [matcher]
            else:
                stack.append(token)

        if len(stack) != 1:
            raise RuntimeError('Unable to build a valid expression. The RPN stack should have just one item.')

        matcher = stack.pop()

        # If a description has been given include it in the matcher
        if self.description:
            matcher = hc.described_as(self.description, matcher)

        return matcher
Пример #5
0
    def evaluate(self):
        """ Converts the current expression into a single matcher, applying
            coordination operators to operands according to their binding rules
        """

        # Apply Shunting Yard algorithm to convert the infix expression
        # into Reverse Polish Notation. Since we have a very limited
        # set of operators and binding rules, the implementation becomes
        # really simple. The expression is formed of hamcrest matcher instances
        # and operators identifiers (ints).
        ops = []
        rpn = []
        for token in self.expr:
            if isinstance(token, int):
                while len(ops) and token <= ops[-1]:
                    rpn.append(ops.pop())
                ops.append(token)
            else:
                rpn.append(token)

        # Append the remaining operators
        while len(ops):
            rpn.append(ops.pop())

        # Walk the RPN expression to create AllOf/AnyOf matchers
        stack = []
        for token in rpn:
            if isinstance(token, int):
                # Handle the NOT case in a special way since it's unary
                if token == OPERATOR.NOT:
                    stack[-1] = IsNot(stack[-1])
                    continue

                # Our operators always need two operands
                if len(stack) < 2:
                    raise RuntimeError('Unable to build a valid expression. Not enough operands available.')

                # Check what kind of matcher we need to create
                if token == OPERATOR.OR:
                    matcher = hc.any_of(*stack[-2:])
                else:  # AND, BUT
                    matcher = hc.all_of(*stack[-2:])

                stack[-2:] = [matcher]
            else:
                stack.append(token)

        if len(stack) != 1:
            raise RuntimeError('Unable to build a valid expression. The RPN stack should have just one item.')

        matcher = stack.pop()

        # If a description has been given include it in the matcher
        if self.description:
            matcher = hc.described_as(self.description, matcher)

        return matcher
Пример #6
0
def has_table_with_rows(table: str, row_matcher: Matcher) -> Matcher:
    """TODO"""
    select = f"SELECT * FROM {table};"  # nosec
    return described_as(
        "DB connection with table %0 with rows matching %1",
        given_select_returns_rows_matching(select, row_matcher),
        table,
        row_matcher,
    )
Пример #7
0
def redirects_to(url_matcher: Union[str, Matcher]) -> Matcher[Response]:
    """Is a response a redirect to a URL matching the suplplied matcher? Matches :requests.models.Response:.
    :param url_matcher: Expected URL.
    """
    return described_as(
        str(StringDescription().append_text(
            "redirects to ").append_description_of(url_matcher)),
        is_response().with_status_code(between(300, 399)).and_headers(
            has_entry("Location", url_matcher)),
    )
Пример #8
0
    def test_start_passes_args_to_task(self):
        def check_args(one, two, key):
            if one == 1 and two == 2 and key == 3:
                return 0
            else:
                return -1

        task = Task(check_args, (1, 2), kwargs={'key': 3})
        task.start()
        task.join()
        assert_that(task.exitcode, described_as(
            'correct arguments were passed to function', is_(0)))
Пример #9
0
def has_properties(*keys_valuematchers, **kv_args):
    """Matches if an object has properties satisfying all of a dictionary
    of string property names and corresponding value matchers.

    :param matcher_dict: A dictionary mapping keys to associated value matchers,
        or to expected values for
        :py:func:`~hamcrest.core.core.isequal.equal_to` matching.

    Note that the keys must be actual keys, not matchers. Any value argument
    that is not a matcher is implicitly wrapped in an
    :py:func:`~hamcrest.core.core.isequal.equal_to` matcher to check for
    equality.

    Examples::

        has_properties({'foo':equal_to(1), 'bar':equal_to(2)})
        has_properties({'foo':1, 'bar':2})

    ``has_properties`` also accepts a list of keyword arguments:

    .. function:: has_properties(keyword1=value_matcher1[, keyword2=value_matcher2[, ...]])

    :param keyword1: A keyword to look up.
    :param valueMatcher1: The matcher to satisfy for the value, or an expected
        value for :py:func:`~hamcrest.core.core.isequal.equal_to` matching.

    Examples::

        has_properties(foo=equal_to(1), bar=equal_to(2))
        has_properties(foo=1, bar=2)

    Finally, ``has_properties`` also accepts a list of alternating keys and their
    value matchers:

    .. function:: has_properties(key1, value_matcher1[, ...])

    :param key1: A key (not a matcher) to look up.
    :param valueMatcher1: The matcher to satisfy for the value, or an expected
        value for :py:func:`~hamcrest.core.core.isequal.equal_to` matching.

    Examples::

        has_properties('foo', equal_to(1), 'bar', equal_to(2))
        has_properties('foo', 1, 'bar', 2)

    """
    if len(keys_valuematchers) == 1:
        try:
            base_dict = keys_valuematchers[0].copy()
            for key in base_dict:
                base_dict[key] = wrap_shortcut(base_dict[key])
        except AttributeError:
            raise ValueError('single-argument calls to has_properties must pass a dict as the argument')
    else:
        if len(keys_valuematchers) % 2:
            raise ValueError('has_properties requires key-value pairs')
        base_dict = {}
        for index in range(int(len(keys_valuematchers) / 2)):
            base_dict[keys_valuematchers[2 * index]] = wrap_shortcut(keys_valuematchers[2 * index + 1])

    for key, value in kv_args.items():
        base_dict[key] = wrap_shortcut(value)

    if len(base_dict) > 1:
        description = StringDescription().append_text('an object with properties ')
        for i, (property_name, property_value_matcher) in enumerate(sorted(base_dict.items())):
            description.append_value(property_name).append_text(' matching ').append_description_of(
                property_value_matcher)
            if i < len(base_dict) - 1:
                description.append_text(' and ')

        return described_as(str(description),
                            AllOf(*[has_property(property_name, property_value_matcher)
                                    for property_name, property_value_matcher
                                    in sorted(base_dict.items())],
                                  describe_all_mismatches=True,
                                  describe_matcher_in_mismatch=False))
    else:
        property_name, property_value_matcher = base_dict.popitem()
        return has_property(property_name, property_value_matcher)
Пример #10
0
def is_weekday() -> Matcher[date]:
    """Match if date is a weekday."""
    matcher = HasWeekday(between(0, 4))
    return described_as("A weekday", matcher)
Пример #11
0
def nothing():
    return described_as("nothing", none())
Пример #12
0
 def wait_until_started_or_fail(self, timeout=5):
     assert_that(
         self.is_started(timeout), described_as(
             'Task started within %0 seconds.', is_(True), timeout))
Пример #13
0
def nothing():
    return described_as("nothing", none())