def test_lower_items(self):
     cid = CaseInsensitiveDict({
         'Accept': 'application/json',
         'user-Agent': 'requests',
     })
     keyset = frozenset(lowerkey for lowerkey, v in cid.lower_items())
     lowerkeyset = frozenset(['accept', 'user-agent'])
     assert keyset == lowerkeyset
Exemple #2
0
 def test_lower_items(self):
     cid = CaseInsensitiveDict({
         'Accept': 'application/json',
         'user-Agent': 'requests',
     })
     keyset = frozenset(lowerkey for lowerkey, v in cid.lower_items())
     lowerkeyset = frozenset(['accept', 'user-agent'])
     assert keyset == lowerkeyset
Exemple #3
0
class TestCaseInsensitiveDict:
    @pytest.fixture(autouse=True)
    def setup(self):
        """CaseInsensitiveDict instance with "Accept" header."""
        self.case_insensitive_dict = CaseInsensitiveDict()
        self.case_insensitive_dict["Accept"] = "application/json"

    def test_list(self):
        assert list(self.case_insensitive_dict) == ["Accept"]

    possible_keys = pytest.mark.parametrize(
        "key", ("accept", "ACCEPT", "aCcEpT", "Accept")
    )

    @possible_keys
    def test_getitem(self, key):
        assert self.case_insensitive_dict[key] == "application/json"

    @possible_keys
    def test_delitem(self, key):
        del self.case_insensitive_dict[key]
        assert key not in self.case_insensitive_dict

    def test_lower_items(self):
        assert list(self.case_insensitive_dict.lower_items()) == [
            ("accept", "application/json")
        ]

    def test_repr(self):
        assert repr(self.case_insensitive_dict) == "{'Accept': 'application/json'}"

    def test_copy(self):
        copy = self.case_insensitive_dict.copy()
        assert copy is not self.case_insensitive_dict
        assert copy == self.case_insensitive_dict

    @pytest.mark.parametrize(
        "other, result",
        (
            ({"AccePT": "application/json"}, True),
            ({}, False),
            (None, False),
        ),
    )
    def test_instance_equality(self, other, result):
        assert (self.case_insensitive_dict == other) is result
Exemple #4
0
class TestCaseInsensitiveDict:

    @pytest.fixture(autouse=True)
    def setup(self):
        """
        CaseInsensitiveDict instance with "Accept" header.
        """
        self.case_insensitive_dict = CaseInsensitiveDict()
        self.case_insensitive_dict['Accept'] = 'application/json'

    def test_list(self):
        assert list(self.case_insensitive_dict) == ['Accept']

    possible_keys = pytest.mark.parametrize('key', ('accept', 'ACCEPT', 'aCcEpT', 'Accept'))

    @possible_keys
    def test_getitem(self, key):
        assert self.case_insensitive_dict[key] == 'application/json'

    @possible_keys
    def test_delitem(self, key):
        del self.case_insensitive_dict[key]
        assert key not in self.case_insensitive_dict

    def test_lower_items(self):
        assert list(self.case_insensitive_dict.lower_items()) == [('accept', 'application/json')]

    def test_repr(self):
        assert repr(self.case_insensitive_dict) == "{'Accept': 'application/json'}"

    def test_copy(self):
        copy = self.case_insensitive_dict.copy()
        assert copy is not self.case_insensitive_dict
        assert copy == self.case_insensitive_dict

    @pytest.mark.parametrize(
        'other, result', (
            ({'AccePT': 'application/json'}, True),
            ({}, False),
            (None, False)
        )
    )
    def test_instance_equality(self, other, result):
        assert (self.case_insensitive_dict == other) is result
Exemple #5
0
 def test_lower_items(self):
     cid = CaseInsensitiveDict({"Accept": "application/json", "user-Agent": "requests"})
     keyset = frozenset(lowerkey for lowerkey, v in cid.lower_items())
     lowerkeyset = frozenset(["accept", "user-agent"])
     assert keyset == lowerkeyset
Exemple #6
0
 def headers(self, new_headers: CaseInsensitiveDict):
     self.response_headers = {k: v for k, v in new_headers.lower_items()}
Exemple #7
0
class StateMachine(object):
    """ Helper class that tracks the state of different entities. """
    def __init__(self, bus):
        self._states = CaseInsensitiveDict()
        self._bus = bus
        self._lock = threading.Lock()

    def entity_ids(self, domain_filter=None):
        """ List of entity ids that are being tracked. """
        if domain_filter is not None:
            domain_filter = domain_filter.lower()

            return [
                state.entity_id for key, state in self._states.lower_items()
                if util.split_entity_id(key)[0] == domain_filter
            ]
        else:
            return list(self._states.keys())

    def all(self):
        """ Returns a list of all states. """
        return [state.copy() for state in self._states.values()]

    def get(self, entity_id):
        """ Returns the state of the specified entity. """
        state = self._states.get(entity_id)

        # Make a copy so people won't mutate the state
        return state.copy() if state else None

    def get_since(self, point_in_time):
        """
        Returns all states that have been changed since point_in_time.
        """
        point_in_time = util.strip_microseconds(point_in_time)

        with self._lock:
            return [
                state for state in self._states.values()
                if state.last_updated >= point_in_time
            ]

    def is_state(self, entity_id, state):
        """ Returns True if entity exists and is specified state. """
        return (entity_id in self._states
                and self._states[entity_id].state == state)

    def remove(self, entity_id):
        """ Removes an entity from the state machine.

        Returns boolean to indicate if an entity was removed. """
        with self._lock:
            return self._states.pop(entity_id, None) is not None

    def set(self, entity_id, new_state, attributes=None):
        """ Set the state of an entity, add entity if it does not exist.

        Attributes is an optional dict to specify attributes of this state.

        If you just update the attributes and not the state, last changed will
        not be affected.
        """

        new_state = str(new_state)
        attributes = attributes or {}

        with self._lock:
            old_state = self._states.get(entity_id)

            is_existing = old_state is not None
            same_state = is_existing and old_state.state == new_state
            same_attr = is_existing and old_state.attributes == attributes

            # If state did not exist or is different, set it
            if not (same_state and same_attr):
                last_changed = old_state.last_changed if same_state else None

                state = self._states[entity_id] = \
                    State(entity_id, new_state, attributes, last_changed)

                event_data = {'entity_id': entity_id, 'new_state': state}

                if old_state:
                    event_data['old_state'] = old_state

                self._bus.fire(EVENT_STATE_CHANGED, event_data)

    def track_change(self, entity_ids, action, from_state=None, to_state=None):
        """
        Track specific state changes.
        entity_ids, from_state and to_state can be string or list.
        Use list to match multiple.

        Returns the listener that listens on the bus for EVENT_STATE_CHANGED.
        Pass the return value into hass.bus.remove_listener to remove it.
        """
        from_state = _process_match_param(from_state)
        to_state = _process_match_param(to_state)

        # Ensure it is a lowercase list with entity ids we want to match on
        if isinstance(entity_ids, str):
            entity_ids = (entity_ids.lower(), )
        else:
            entity_ids = tuple(entity_id.lower() for entity_id in entity_ids)

        @ft.wraps(action)
        def state_listener(event):
            """ The listener that listens for specific state changes. """
            if event.data['entity_id'].lower() in entity_ids and \
                    'old_state' in event.data and \
                    _matcher(event.data['old_state'].state, from_state) and \
                    _matcher(event.data['new_state'].state, to_state):

                action(event.data['entity_id'], event.data['old_state'],
                       event.data['new_state'])

        self._bus.listen(EVENT_STATE_CHANGED, state_listener)

        return state_listener