def test_operators_nested_simple(): events = [ UserUttered(intent={"name": "1"}), UserUttered(intent={"name": "2"}), UserUttered(intent={"name": "3"}), SlotSet("s1", value="any"), UserUttered(intent={"name": "4"}), UserUttered(intent={"name": "5"}), UserUttered(intent={"name": "6"}), ] marker = AndMarker( markers=[ SlotSetMarker("s1"), OrMarker([ IntentDetectedMarker("4"), IntentDetectedMarker("6"), ]), ], name="marker_name", ) evaluation = marker.evaluate_events(events) assert len(evaluation[0]["marker_name"]) == 2 assert evaluation[0]["marker_name"][0].preceding_user_turns == 3 assert evaluation[0]["marker_name"][1].preceding_user_turns == 5
def test_marker_from_config(): config = { AndMarker.positive_tag(): [ { SlotSetMarker.positive_tag(): "s1" }, { OrMarker.positive_tag(): [ { IntentDetectedMarker.positive_tag(): "4" }, { IntentDetectedMarker.negated_tag(): "6" }, ] }, ] } marker = Marker.from_config(config) assert isinstance(marker, AndMarker) assert isinstance(marker.sub_markers[0], SlotSetMarker) or_marker = marker.sub_markers[1] assert isinstance(or_marker, OrMarker) for sub_marker in or_marker.sub_markers: assert isinstance(sub_marker, ConditionMarker)
def test_operator_or(negated: bool): events = [ UserUttered(intent={INTENT_NAME_KEY: "1"}), UserUttered(intent={INTENT_NAME_KEY: "unknown"}), UserUttered(intent={INTENT_NAME_KEY: "2"}), UserUttered(intent={INTENT_NAME_KEY: "unknown"}), ] sub_markers = [IntentDetectedMarker("1"), IntentDetectedMarker("2")] marker = OrMarker(sub_markers, name="marker_name", negated=negated) for event in events: marker.track(event) expected = [True, False, True, False] if negated: expected = [not applies for applies in expected] assert marker.history == expected
def test_operator_occur(negated: bool): events_expected = [ (UserUttered(intent={INTENT_NAME_KEY: "0"}), False), (SlotSet("2", value=None), False), (UserUttered(intent={INTENT_NAME_KEY: "1"}), True), (SlotSet("2", value=None), True), (UserUttered(intent={INTENT_NAME_KEY: "2"}), True), (SlotSet("2", value="bla"), True), (UserUttered(intent={INTENT_NAME_KEY: "2"}), True), ] events, expected = zip(*events_expected) sub_marker = OrMarker([IntentDetectedMarker("1"), SlotSetMarker("2")], name="or marker", negated=False) marker = OccurrenceMarker([sub_marker], name="marker_name", negated=negated) for event in events: marker.track(event) expected = list(expected) if negated: expected = [not applies for applies in expected] assert marker.history == expected assert marker.relevant_events() == [expected.index(True)]
def test_operator_seq(negated: bool): events_expected = [ (UserUttered(intent={INTENT_NAME_KEY: "1"}), False), (ActionExecuted( "unrelated event that does not interrupt the sequence"), False), (UserUttered(intent={INTENT_NAME_KEY: "2"}), True), (UserUttered(intent={INTENT_NAME_KEY: "3"}), False), (UserUttered(intent={INTENT_NAME_KEY: "1"}), False), (UserUttered(intent={INTENT_NAME_KEY: "2"}), True), ] events, expected = zip(*events_expected) sub_markers = [IntentDetectedMarker("1"), IntentDetectedMarker("2")] marker = SequenceMarker(sub_markers, name="marker_name", negated=negated) for event in events: marker.track(event) expected = list(expected) if negated: expected = [not applies for applies in expected] assert marker.history == expected
def test_operator_raises_wrong_amount_sub_markers( operator_class: Type[OperatorMarker], negated: bool): expected_number = operator_class.expected_number_of_sub_markers() one_more_than_expected = [ IntentDetectedMarker("bla") for _ in range(expected_number + 1) ] with pytest.raises(InvalidMarkerConfig): operator_class(one_more_than_expected, name="marker_name", negated=negated)
def test_operator_seq_does_not_allow_overlap(negated: bool): events_expected = [ (UserUttered(intent={INTENT_NAME_KEY: "1"}), False), (UserUttered(intent={INTENT_NAME_KEY: "2"}), False), (UserUttered(intent={INTENT_NAME_KEY: "1"}), False), (UserUttered(intent={INTENT_NAME_KEY: "2"}), False), (UserUttered(intent={INTENT_NAME_KEY: "3"}), True), (UserUttered(intent={INTENT_NAME_KEY: "3"}), False), ] events, expected = zip(*events_expected) sub_markers = [ IntentDetectedMarker("1"), IntentDetectedMarker("2"), IntentDetectedMarker("3"), ] marker = SequenceMarker(sub_markers, name="marker_name", negated=negated) for event in events: marker.track(event) expected = list(expected) if negated: expected = [not applies for applies in expected] assert marker.history == expected
def test_marker_from_path_only_reads_yamls(tmp_path: Path): suffixes = [("yaml", True), ("yml", True), ("yaeml", False), ("config", False)] for idx, (suffix, allowed) in enumerate(suffixes): config = { f"marker-{idx}": { IntentDetectedMarker.positive_tag(): "intent" } } config_file = tmp_path / f"config-{idx}.{suffix}" rasa.shared.utils.io.write_yaml(data=config, target=config_file) loaded = Marker.from_path(tmp_path) assert len(loaded.sub_markers) == sum(allowed for _, allowed in suffixes) assert set(sub_marker.name for sub_marker in loaded.sub_markers) == set( f"marker-{idx}" for idx, (_, allowed) in enumerate(suffixes) if allowed)
def test_operator_occur_never_applied_negated(): events_expected = [ (UserUttered(intent={INTENT_NAME_KEY: "1"}), False), (SlotSet("2", value=None), False), (UserUttered(intent={INTENT_NAME_KEY: "0"}), False), (SlotSet("1", value="test"), False), ] events, expected = zip(*events_expected) sub_marker = OrMarker([IntentDetectedMarker("1"), SlotSetMarker("2")], name="or marker", negated=False) marker = OccurrenceMarker([sub_marker], name="or never occurred", negated=True) for event in events: marker.track(event) assert marker.relevant_events() == []
def test_operator_and(negated: bool): events_expected = [ (UserUttered(intent={INTENT_NAME_KEY: "1"}), False), (SlotSet("2", value="bla"), False), (UserUttered(intent={INTENT_NAME_KEY: "1"}), True), (SlotSet("2", value=None), False), (UserUttered(intent={INTENT_NAME_KEY: "1"}), False), (SlotSet("2", value="bla"), False), (UserUttered(intent={INTENT_NAME_KEY: "2"}), False), ] events, expected = zip(*events_expected) sub_markers = [IntentDetectedMarker("1"), SlotSetMarker("2")] marker = AndMarker(sub_markers, name="marker_name", negated=negated) for event in events: marker.track(event) expected = list(expected) if negated: expected = [not applies for applies in expected] assert marker.history == expected
def test_operator_negated_to_str(marker_class: Type[OperatorMarker]): marker = marker_class([IntentDetectedMarker("bla")], negated=True) if marker.negated_tag() is not None: assert marker.negated_tag() in str(marker)
[{ SlotSetMarker.positive_tag(): "s1" }], # - config is just a str # (2) sub-markers SlotSetMarker.positive_tag(), # - sub-marker config is dict not list { AndMarker.positive_tag(): { SlotSetMarker.positive_tag(): "s1" } }, # - sub-marker under condition { SlotSetMarker.positive_tag(): { IntentDetectedMarker.positive_tag(): "blah" } }, # - no sub-config for operator (see also: "amount_sub_markers" tests) { AndMarker.positive_tag(): "blah" }, # (3) tags # - unknown operator { "Ard": { IntentDetectedMarker.positive_tag(): "intent1" } }, # - unknown condition {