def test_seeker_defaulting_and_chaining(self): '''this action makes the first seeker default''' action = NullAction(rspec="clean") action.set_nexus(self.nexus) alt = MockAlternative(u"my", u"spoken", u"words") sira = StackItemRegisteredAction(action, {"_node": alt}) self.nexus.state.add(sira) # mutable_integer = {"value": 0} def increment(): mutable_integer["value"] += 1 '''make backward seekers''' back_seeker = ContextSeeker(back=[ L(S(["def"], Function(lambda: None)), S(["abc"], Function(increment))) ], rspec="abc") back_seeker.set_nexus(self.nexus) '''create backward seeker stack items''' stack_seeker1 = StackItemSeeker(back_seeker, {"_node": alt}) stack_seeker2 = StackItemSeeker(back_seeker, {"_node": alt}) '''add one''' self.nexus.state.add(stack_seeker1) '''at this point, the first seeker should have defaulted and done nothing''' self.assertEqual(mutable_integer["value"], 0) self.nexus.state.add(stack_seeker2) '''the second context seeker should have been triggered by the first, incrementing the value''' self.assertEqual(mutable_integer["value"], 1)
def test_seeker_backward(self): for i in range(0, 2): '''make 2 fake NullActions''' trigger1 = NullAction(rspec="bell") trigger2 = NullAction(rspec="door") trigger1.set_nexus(self.nexus) trigger2.set_nexus(self.nexus) '''make fake StackItemRegisteredActions''' alt2 = MockAlternative(u"my", u"spoken", u"words") sira1 = StackItemRegisteredAction(trigger1, {"_node": alt2}) sira2 = StackItemRegisteredAction(trigger2, {"_node": alt2}) '''add them''' self.nexus.state.add(sira1) self.nexus.state.add(sira2) '''set up backward looking seeker''' mutable_string = {"value": ""} def append_a(): mutable_string["value"] += "a" def append_b(): mutable_string["value"] += "b" def append_c(): mutable_string["value"] += "c" def append_d(): mutable_string["value"] += "d" '''create context levels''' set_1_1 = S(["arch"], append_a) set_1_2 = S(["bell"], append_b) level_1 = L(set_1_1, set_1_2) set_2_1 = S(["cellar"], append_c) set_2_2 = S(["door"], append_d) level_2 = L(set_2_1, set_2_2) '''create context seeker''' levels = [level_1, level_2] seeker = ContextSeeker(back=levels) if i == 0: seeker.reverse = True seeker.set_nexus(self.nexus) '''create context seeker stack item''' alt = MockAlternative(u"my", u"spoken", u"words") stack_seeker = StackItemSeeker(seeker, {"_node": alt}) '''add it''' self.nexus.state.add(stack_seeker) if i == 0: self.assertEqual(mutable_string["value"], "db") else: self.assertEqual(mutable_string["value"], "bd")
def __init__(self, node, nexus, is_reset=False): first = False if self.master_node is None: self.master_node = node self.nexus = nexus '''self.post is added to every entry in the mapping; its purpose is to handle cancels; if it detects another of itself, it does nothing; but looking forward, won't it never find itself? how is it that the node isn't constantly getting reset? ''' self.post = ContextSeeker(forward=[ L(S(["cancel"], lambda: self.reset_node(), consume=False), S([self.master_node.spec], lambda: None, consume=False)) ], rspec=self.master_node.spec) self.post.set_nexus(nexus) first = True SelfModifyingRule.__init__(self, self.master_node.spec, refresh=False) self.refresh(node, first, is_reset)
class NodeRule(SelfModifyingRule): master_node = None def __init__(self, node, nexus, is_reset=False): first = False if self.master_node is None: self.master_node = node self.nexus = nexus '''self.post is added to every entry in the mapping; its purpose is to handle cancels; if it detects another of itself, it does nothing; but looking forward, won't it never find itself? how is it that the node isn't constantly getting reset? ''' self.post = ContextSeeker(forward=[ L(S(["cancel"], lambda: self.reset_node(), consume=False), S([self.master_node.spec], lambda: None, consume=False)) ], rspec=self.master_node.spec) self.post.set_nexus(nexus) first = True SelfModifyingRule.__init__(self, self.master_node.spec, refresh=False) self.refresh(node, first, is_reset) def get_pronunciation(self): return self.master_node.spec def refresh(self, *args): self.node = args[0] first = args[1] is_reset = args[2] mapping = {} extras = [] defaults = {} '''each child node gets turned into a mapping key/value''' for child in self.node.children: child.fill_out_rule(mapping, extras, defaults, self) if len(mapping) == 0: self.reset_node() for child in self.node.children: child.fill_out_rule(mapping, extras, defaults, self) else: if not first and not is_reset: # sta#tus win#dow messaging choices = [ x.get_spec_and_base_and_node()[0] for x in self.node.children ] #for choice in choices: # self.nexus.intermediary.text(choice) self.extras = extras self.defaults = defaults self.reset(mapping) def change_node(self, node, reset=False): self.refresh(node, False, reset) def reset_node(self): if self.node is not self.master_node: self.change_node(self.master_node, True)
class StackTest(MappingRule): '''test battery for the ContextStack''' mapping = { "close last tag": ContextSeeker([ L( S(["cancel"], None), S(["html spoken"], close_last_spoken, use_spoken=True), S(["span", "div"], close_last_rspec, use_rspec=True)) ]), "html": R(Text("<html>")), "divider": R(Text("<div>")), "span": R(Text("<span>")), "backward seeker [<text>]": ContextSeeker([ L( S(["ashes"], Text("ashes1 [%(text)s] ")), S(["bravery"], Text("bravery1 [%(text)s] "))), L( S(["ashes"], Text("ashes2 [%(text)s] ")), S(["bravery"], Text("bravery2 [%(text)s] "))) ]), "forward seeker [<text>]": ContextSeeker(forward=[ L( S(["ashes"], Text("ashes1 [%(text)s] ")), S(["bravery"], Text("bravery1 [%(text)s] "))), L( S(["ashes"], Text("ashes2 [%(text)s] ")), S(["bravery"], Text("bravery2 [%(text)s] "))) ]), "asynchronous test": AsynchronousAction([ L( S(["ashes", "charcoal"], print_time, None), S(["bravery"], Text, "bravery1")) ], time_in_seconds=0.2, repetitions=20, finisher=Text(FINISHER_TEXT), blocking=False), "ashes": RegisteredAction(Text("ashes _ ")), "bravery": RegisteredAction(Text("bravery _ ")), "charcoal <text> [<n>]": R(Text("charcoal _ %(text)s")), "test confirm action": ConfirmAction( Key("a"), rdescript="Confirm Action Test", instructions="some words here"), "test box action": BoxAction( lambda data: _abc(data), rdescript="Test Box Action", box_type=settings.QTYPE_DEFAULT, log_failure=True), } extras = [Dictation("text"), Dictation("text2"), IntegerRefST("n", 1, 5)] defaults = {"text": "", "text2": ""}
def test_use_spoken_words_or_rspec(self): '''seekers can take the spoken words or rspecs of their trigger actions and feed them to the function objects of their ContextSets''' '''make triggers for context seekers (2 forward, 2 backward / 2 spoken, 2 rspec)''' action1 = NullAction(rspec="alpha") action2 = NullAction(rspec="_") action3 = NullAction(rspec="charlie") action4 = NullAction(rspec="_") action1.set_nexus(self.nexus) action2.set_nexus(self.nexus) action3.set_nexus(self.nexus) action4.set_nexus(self.nexus) alt = MockAlternative(u"_") spec1 = [u"here", u"are", u"words"] spec2 = [u"some", u"more", u"words"] sira1 = StackItemRegisteredAction(action1, {"_node": alt}) sira2 = StackItemRegisteredAction(action2, {"_node": MockAlternative(*spec1)}) sira3 = StackItemRegisteredAction(action3, {"_node": alt}) sira4 = StackItemRegisteredAction(action4, {"_node": MockAlternative(*spec2)}) # mutable_integer = {"value": 0} def increment(): mutable_integer["value"] += 1 # def _1(params): if params == "alpha": increment() def _2(params): if params == spec1: increment() def _3(params): if params == "charlie": increment() def _4(params): if params == spec2: increment() '''make seekers''' back_seeker1 = ContextSeeker( back=[L(S(["alpha"], _1, parameters="_", use_rspec=True))], rspec="_") back_seeker2 = ContextSeeker( back=[L(S(["_"], _2, parameters=["_"], use_spoken=True))], rspec="_") forward_seeker1 = ContextSeeker( forward=[L(S(["_"], _3, parameters="_", use_rspec=True))], rspec="_") forward_seeker2 = ContextSeeker( forward=[L(S(["delta"], _4, parameters=["_"], use_spoken=True))], rspec="_") back_seeker1.set_nexus(self.nexus) back_seeker2.set_nexus(self.nexus) forward_seeker1.set_nexus(self.nexus) forward_seeker2.set_nexus(self.nexus) '''create seeker stack items''' stack_seeker_b1 = StackItemSeeker(back_seeker1, {"_node": alt}) stack_seeker_b2 = StackItemSeeker(back_seeker2, {"_node": alt}) stack_seeker_f1 = StackItemSeeker(forward_seeker1, {"_node": alt}) stack_seeker_f2 = StackItemSeeker(forward_seeker2, {"_node": alt}) # '''trigger the first backward seeker; uses rspec ("alpha") ''' self.nexus.state.add(sira1) self.nexus.state.add(stack_seeker_b1) self.assertEqual(mutable_integer["value"], 1) '''trigger the second backward seeker; uses spoken words (spec1) ''' self.nexus.state.add(sira2) self.nexus.state.add(stack_seeker_b2) self.assertEqual(mutable_integer["value"], 2) '''trigger the first forward seeker; uses rspec ("charlie") ''' self.nexus.state.add(stack_seeker_f1) self.nexus.state.add(sira3) self.assertEqual(mutable_integer["value"], 3) '''trigger the first forward seeker; uses spoken words (spec2) ''' self.nexus.state.add(stack_seeker_f2) self.nexus.state.add(sira4) self.assertEqual(mutable_integer["value"], 4)
def test_actions_cleaned(self): '''these test functions should stay in sync with the clean methods for each stack action''' def registered_is_clean(r): return r.dragonfly_data is None and r.base is None def seeker_is_clean(s): result = True levels = [] if s.back is not None: levels += s.back if s.forward is not None: levels += s.forward for context_level in levels: result &= context_level.dragonfly_data is None return result def asynchronous_is_clean(a): return a.closure is None '''mock words being the same doesn't matter for this test, or most tests''' alt = MockAlternative(u"my", u"spoken", u"words") '''make fake NullActions''' action1 = NullAction(rspec="barkley") action2 = NullAction(rspec="gaiden") action3 = NullAction(rspec="is") action4 = NullAction(rspec="awesome") action1.set_nexus(self.nexus) action2.set_nexus(self.nexus) action3.set_nexus(self.nexus) action4.set_nexus(self.nexus) '''make fake StackItemRegisteredActions''' sira1 = StackItemRegisteredAction(action1, {"_node": alt}) sira2 = StackItemRegisteredAction(action2, {"_node": alt}) sira3 = StackItemRegisteredAction(action3, {"_node": alt}) sira4 = StackItemRegisteredAction(action4, {"_node": alt}) '''should not be clean before it's executed''' self.assertFalse(registered_is_clean(sira1)) '''add first one for backward seeker''' self.nexus.state.add(sira1) '''should be clean as soon as it's executed''' self.assertTrue(registered_is_clean(sira1)) '''make backward seeker''' back_seeker = ContextSeeker( back=[L(S(["minecraft"], Function(lambda: None)))]) back_seeker.set_nexus(self.nexus) '''create backward seeker stack item''' stack_seeker = StackItemSeeker(back_seeker, {"_node": alt}) '''add it''' self.nexus.state.add(stack_seeker) '''levels should be clean as soon as it's executed''' self.assertTrue( registered_is_clean(stack_seeker) and seeker_is_clean(stack_seeker)) # '''make forward seeker''' forward_seeker = ContextSeeker(forward=[ L(S(["cave"], Function(lambda: None))), L(S(["story"], Function(lambda: None))) ]) forward_seeker.set_nexus(self.nexus) '''create context seeker stack item''' stack_seeker2 = StackItemSeeker(forward_seeker, {"_node": alt}) '''add it''' self.nexus.state.add(stack_seeker2) self.nexus.state.add(sira2) '''levels should not be clean before seeker is executed''' self.assertFalse( registered_is_clean(stack_seeker2) or seeker_is_clean(stack_seeker2)) self.nexus.state.add(sira3) '''levels should be clean as soon as it's executed''' self.assertTrue( registered_is_clean(stack_seeker2) and seeker_is_clean(stack_seeker2)) # '''make asynchronous action''' asynchronous = AsynchronousAction( [L(S(["eternal", "daughter", "awesome"], lambda: None))], blocking=False) asynchronous.set_nexus(self.nexus) '''make StackItemAsynchronous''' sia1 = StackItemAsynchronous(asynchronous, {"_node": alt}) '''add it''' self.nexus.state.add(sia1) '''closure should not be clean before asynchronous is executed''' self.assertFalse( registered_is_clean(sia1) or seeker_is_clean(sia1) or asynchronous_is_clean(sia1)) self.nexus.state.add(sira4) '''closure should be clean after asynchronous is executed''' self.assertTrue( registered_is_clean(sia1) and seeker_is_clean(sia1) and asynchronous_is_clean(sia1))
def test_seeker_consume(self): '''seeker actions have the option to not/consume their triggers; that is, the trigger actions do not execute and only act as triggers''' mutable_string = {"value": ""} def append_a(): mutable_string["value"] += "a" def append_b(): mutable_string["value"] += "b" def append_c(): mutable_string["value"] += "c" def append_d(): mutable_string["value"] += "d" def append_e(): mutable_string["value"] += "e" def append_f(): mutable_string["value"] += "f" '''create context levels''' set_1_1 = S(["arch"], append_a) set_1_2 = S(["bell"], append_b) set_1_2.consume = False level_1 = L(set_1_1, set_1_2) set_2_1 = S(["cellar"], append_c) set_2_2 = S(["door"], append_d) level_2 = L(set_2_1, set_2_2) set_3_1 = S(["echo"], append_e) set_3_2 = S(["frame"], append_f) set_3_2.consume = False level_3 = L(set_3_1, set_3_2) '''create context seeker''' levels = [level_1, level_2, level_3] seeker = ContextSeeker(forward=levels) seeker.set_nexus(self.nexus) '''create context seeker stack item''' alt = MockAlternative(u"my", u"spoken", u"words") stack_seeker = StackItemSeeker(seeker, {"_node": alt}) '''add it''' self.nexus.state.add(stack_seeker) '''make 3 fake triggering RegisteredActions; the first and third do not consume their triggers''' trigger1 = RegisteredAction(Function(append_a), rspec="bell") trigger2 = RegisteredAction(Function(append_c), rspec="door") trigger3 = RegisteredAction(Function(append_e), rspec="frame") trigger1.set_nexus(self.nexus) trigger2.set_nexus(self.nexus) trigger3.set_nexus(self.nexus) '''make fake StackItemRegisteredActions''' alt2 = MockAlternative(u"my", u"spoken", u"words") sira1 = StackItemRegisteredAction(trigger1, {"_node": alt2}) sira2 = StackItemRegisteredAction(trigger2, {"_node": alt2}) sira3 = StackItemRegisteredAction(trigger3, {"_node": alt2}) '''add them''' self.nexus.state.add(sira1) self.nexus.state.add(sira2) self.nexus.state.add(sira3) self.assertEqual(mutable_string["value"], "aebdf")