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
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
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
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
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
def headers(self, new_headers: CaseInsensitiveDict): self.response_headers = {k: v for k, v in new_headers.lower_items()}
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