def __init__(self, name): config_script = { 'VERSION' : { '*' : [('VERSION', CANTO_PROTOCOL_COMPATIBLE)] }, 'CONFIGS' : { '*' : [('CONFIGS', { "CantoCurses" : config.template_config })] }, 'PING' : { '*' : [("PONG", [])]} } self.config_backend = TestBackend("config", config_script) config.init(self.config_backend, CANTO_PROTOCOL_COMPATIBLE) self.config_backend.inject("NEWTAGS", [ "maintag:Tag(0)", "maintag:Tag(1)", "maintag:Tag(2)" ]) tagcore_script = generate_item_script(3, 20, "maintag:Tag(%d)", "Story(%d,%d)", { "title" : "%d,%d - title", "link" : "http://example.com/%d/%d", "description" : "Description(%d,%d)", "canto-tags" : "", "canto-state" : "" } ) self.tag_backend = TestBackend("tagcore", tagcore_script) gui_script = {} self.gui_backend = TestBackend("gui", gui_script) self.glog = GraphicalLog() self.gui = CantoCursesGui(self.gui_backend, self.glog) tag_updater.init(self.tag_backend) # The standard opening of c-c, the tags can be in any state, but for the # purposes of testing, we want to make sure that the tagcores are in a known # state or the rest of this stuff will be racy. # Fortunately the real-world opening case is tested every time you run c-c =P # 9 = 3 tags * 3 responses per ITEMS call (ITEMS, ITEMSDONE, and ATTRIBUTES) while len(self.tag_backend.procd) != 9: print("len: %s" % len(self.tag_backend.procd)) time.sleep(0.1) if len(alltagcores) != 3: raise Exception("Didn't get all tags!") if len(alltagcores[0]) != 20: raise Exception("Didn't get all items in tagcore[0]") if len(alltagcores[1]) != 20: raise Exception("Didn't get all items in tagcore[1]") self.wait_on_update() Test.__init__(self, name)
def __init__(self, name): config_script = { 'VERSION' : { '*' : [('VERSION', CANTO_PROTOCOL_COMPATIBLE)] }, 'CONFIGS' : { '*' : [('CONFIGS', { "CantoCurses" : config.template_config })] }, } self.config_backend = TestBackend("config", config_script) config.init(self.config_backend, CANTO_PROTOCOL_COMPATIBLE) self.config_backend.inject("NEWTAGS", [ "maintag:Tag(0)", "maintag:Tag(1)", "maintag:Tag(2)" ]) tagcore_script = generate_item_script(3, 20, "maintag:Tag(%d)", "Story(%d,%d)", { "title" : "%d,%d - title", "link" : "http://example.com/%d/%d", "description" : "Description(%d,%d)", "canto-tags" : "", "canto-state" : "" } ) self.tag_backend = TestBackend("tagcore", tagcore_script) tag_updater.init(self.tag_backend) # The standard opening of c-c, the tags can be in any state, but for the # purposes of testing, we want to make sure that the tagcores are in a known # state or the rest of this stuff will be racy. # Fortunately the real-world opening case is tested every time you run c-c =P # 9 = 3 tags * 3 responses per ITEMS call (ITEMS, ITEMSDONE, and ATTRIBUTES) while len(self.tag_backend.procd) != 9: print("len: %s" % len(self.tag_backend.procd)) time.sleep(0.1) if len(alltagcores) != 3: raise Exception("Didn't get all tags!") if len(alltagcores[0]) != 20: raise Exception("Didn't get all items in tagcore[0]") if len(alltagcores[1]) != 20: raise Exception("Didn't get all items in tagcore[1]") gui_script = {} self.gui_backend = TestBackend("gui", gui_script) self.gui = CantoCursesGui(self.gui_backend) self.wait_on_update() Test.__init__(self, name)
def check(self): script = { 'VERSION' : { '*' : [('VERSION', CANTO_PROTOCOL_COMPATIBLE)] }, 'CONFIGS' : { '*' : [('CONFIGS', { "CantoCurses" : config.template_config })] }, } backend = TestBackend("config", script) config.init(backend, CANTO_PROTOCOL_COMPATIBLE) # We only want to test failure. Success will be tested by the config hook test. really_bad_config = eval(repr(config.template_config)) really_bad_config["browser"]["text"] = "badoption" backend.inject("CONFIGS", { "CantoCurses" : really_bad_config }) return config.config == config.template_config
def check(self): script = { 'VERSION': { '*': [('VERSION', CANTO_PROTOCOL_COMPATIBLE)] }, 'CONFIGS': { '*': [('CONFIGS', { "CantoCurses": config.template_config })] }, } backend = TestBackend("config", script) config.init(backend, CANTO_PROTOCOL_COMPATIBLE) # We only want to test failure. Success will be tested by the config hook test. really_bad_config = eval(repr(config.template_config)) really_bad_config["browser"]["text"] = "badoption" backend.inject("CONFIGS", {"CantoCurses": really_bad_config}) return config.config == config.template_config
def check(self): config_script = { 'VERSION' : { '*' : [('VERSION', CANTO_PROTOCOL_COMPATIBLE)] }, 'CONFIGS' : { '*' : [('CONFIGS', { "CantoCurses" : config.template_config })] }, } config_backend = TestBackend("config", config_script) config.init(config_backend, CANTO_PROTOCOL_COMPATIBLE) config_backend.inject("NEWTAGS", [ "maintag:Slashdot", "maintag:reddit" ]) tagcore_script = {} tag_backend = TestBackend("tagcore", tagcore_script) on_hook("curses_items_removed", self.on_items_removed) on_hook("curses_items_added", self.on_items_added) on_hook("curses_new_tagcore", self.on_new_tagcore) on_hook("curses_del_tagcore", self.on_del_tagcore) on_hook("curses_attributes", self.on_attributes) on_hook("curses_update_complete", self.on_update_complete) on_hook("curses_tag_updated", self.on_tag_updated) # 1. Previously existing tags in config should be populated on init self.reset_flags() tag_updater.init(tag_backend) for tag in config.vars["strtags"]: for tc in alltagcores: if tc.tag == tag: break else: raise Exception("Couldn't find TC for tag %s" % tag) self.compare_flags(NEW_TC) self.reset_flags() # 2. Getting empty ITEMS responses should cause no events tag_backend.inject("ITEMS", { "maintag:Slashdot" : [] }) tag_backend.inject("ITEMSDONE", {}) tag_backend.inject("ITEMS", { "maintag:reddit" : [] }) tag_backend.inject("ITEMSDONE", {}) self.compare_flags(0) # 3. Getting a non-empty ITEMS response should cause items_added tag_backend.inject("ITEMS", { "maintag:Slashdot" : [ "id1", "id2" ] }) tag_backend.inject("ITEMSDONE", {}) self.compare_flags(ITEMS_ADDED) # 4. Getting attributes should cause attributes hook self.reset_flags() id1_content = { "title" : "id1", "canto-state" : [], "canto-tags" : [], "link" : "id1-link", "enclosures" : "" } id2_content = { "title" : "id2", "canto-state" : [], "canto-tags" : [], "link" : "id2-link", "enclosures" : "" } all_content = { "id1" : id1_content, "id2" : id2_content } tag_backend.inject("ATTRIBUTES", all_content) self.compare_flags(ATTRIBUTES) self.compare_var("attributes", all_content) id1_got = tag_updater.get_attributes("id1") if id1_got != id1_content: raise Exception("Bad content: wanted %s - got %s" % (id1_content, id1_got)) id2_got = tag_updater.get_attributes("id2") if id2_got != id2_content: raise Exception("Bad content: wanted %s - got %s" % (id2_content, id2_got)) # 5. Removing an item should *NOT* cause its attributes to be forgotten # that happens on stories_removed, and should cause ITEMS_REMOVED self.reset_flags() tag_backend.inject("ITEMS", { "maintag:Slashdot" : [ "id1" ] }) tag_backend.inject("ITEMSDONE", {}) self.compare_flags(ITEMS_REMOVED) id2_got = tag_updater.get_attributes("id2") if id2_got != id2_content: raise Exception("Bad content: wanted %s - got %s" % (id2_content, id2_got)) # 6. Getting a stories_removed hook should make it forget attributes self.reset_flags() call_hook("curses_stories_removed", [ FakeTag("maintag:Slashdot"), [ FakeStory("id2") ] ]) if "id2" in tag_updater.attributes: raise Exception("Expected id2 to be removed, but it isn't!") self.compare_flags(0) # 7. Getting attributes for non-existent IDs should return empty id2_got = tag_updater.get_attributes("id2") if id2_got != {}: raise Exception("Expected non-existent id to return empty! Got %s" % id2_got) self.compare_flags(0) # 8. Getting stories_removed for item still in tag should do nothing call_hook("curses_stories_removed", [ FakeTag("maintag:Slashdot"), [ FakeStory("id1") ] ]) if "id1" not in tag_updater.attributes: raise Exception("Expected id1 to remain in attributes!") self.compare_flags(0) # 9. Config adding a tag should create a new tagcore config_backend.inject("NEWTAGS", [ "maintag:Test1" ]) self.compare_flags(NEW_TC) # 10. Config removing an empty tag should delete a tagcore self.reset_flags() config_backend.inject("DELTAGS", [ "maintag:reddit" ]) self.compare_flags(DEL_TC) self.compare_var("del_tc", "maintag:reddit") # 11. Config removing an populated tag should delete a tagcore and # cause items_removed. NOTE for now tagcores are never deleted, they # just exist empty self.reset_flags() config_backend.inject("DELTAGS", [ "maintag:Slashdot" ]) self.compare_flags(DEL_TC | ITEMS_REMOVED) self.compare_var("del_tc", "maintag:Slashdot") self.compare_var("oir_tctag", "maintag:Slashdot") self.compare_var("oir_tcids", [ "id1" ]) # 12. Update should cause all tags to generate a tag_update # hook call on ITEMS, and update_complete when all done. self.reset_flags() tag_updater.update() tag_backend.inject("ITEMS", { "maintag:Test1" : [ "id3", "id4" ] }) tag_backend.inject("ITEMSDONE", {}) tag_backend.inject("ATTRIBUTES", { "id3" : { "test" : "test" }, "id4" : { "test" : "test" }}) print(tag_updater.updating) self.compare_flags(TAG_UPDATED | UPDATE_COMPLETE | ITEMS_ADDED | ATTRIBUTES) self.compare_var("otu_tag", "maintag:Test1") return True
def check(self): config_script = { 'VERSION': { '*': [('VERSION', CANTO_PROTOCOL_COMPATIBLE)] }, 'CONFIGS': { '*': [('CONFIGS', { "CantoCurses": config.template_config })] }, } config_backend = TestBackend("config", config_script) config.init(config_backend, CANTO_PROTOCOL_COMPATIBLE) config_backend.inject("NEWTAGS", ["maintag:Slashdot", "maintag:reddit"]) tagcore_script = {} tag_backend = TestBackend("tagcore", tagcore_script) on_hook("curses_items_removed", self.on_items_removed) on_hook("curses_items_added", self.on_items_added) on_hook("curses_new_tagcore", self.on_new_tagcore) on_hook("curses_del_tagcore", self.on_del_tagcore) on_hook("curses_attributes", self.on_attributes) on_hook("curses_update_complete", self.on_update_complete) on_hook("curses_tag_updated", self.on_tag_updated) # 1. Previously existing tags in config should be populated on init self.reset_flags() tag_updater.init(tag_backend) for tag in config.vars["strtags"]: for tc in alltagcores: if tc.tag == tag: break else: raise Exception("Couldn't find TC for tag %s" % tag) self.compare_flags(NEW_TC) self.reset_flags() # 2. Getting empty ITEMS responses should cause no events tag_backend.inject("ITEMS", {"maintag:Slashdot": []}) tag_backend.inject("ITEMSDONE", {}) tag_backend.inject("ITEMS", {"maintag:reddit": []}) tag_backend.inject("ITEMSDONE", {}) self.compare_flags(0) # 3. Getting a non-empty ITEMS response should cause items_added tag_backend.inject("ITEMS", {"maintag:Slashdot": ["id1", "id2"]}) tag_backend.inject("ITEMSDONE", {}) self.compare_flags(ITEMS_ADDED) # 4. Getting attributes should cause attributes hook self.reset_flags() id1_content = { "title": "id1", "canto-state": [], "canto-tags": [], "link": "id1-link", "enclosures": "" } id2_content = { "title": "id2", "canto-state": [], "canto-tags": [], "link": "id2-link", "enclosures": "" } all_content = {"id1": id1_content, "id2": id2_content} tag_backend.inject("ATTRIBUTES", all_content) self.compare_flags(ATTRIBUTES) self.compare_var("attributes", all_content) id1_got = tag_updater.get_attributes("id1") if id1_got != id1_content: raise Exception("Bad content: wanted %s - got %s" % (id1_content, id1_got)) id2_got = tag_updater.get_attributes("id2") if id2_got != id2_content: raise Exception("Bad content: wanted %s - got %s" % (id2_content, id2_got)) # 5. Removing an item should *NOT* cause its attributes to be forgotten # that happens on stories_removed, and should cause ITEMS_REMOVED self.reset_flags() tag_backend.inject("ITEMS", {"maintag:Slashdot": ["id1"]}) tag_backend.inject("ITEMSDONE", {}) self.compare_flags(ITEMS_REMOVED) id2_got = tag_updater.get_attributes("id2") if id2_got != id2_content: raise Exception("Bad content: wanted %s - got %s" % (id2_content, id2_got)) # 6. Getting a stories_removed hook should make it forget attributes self.reset_flags() call_hook("curses_stories_removed", [FakeTag("maintag:Slashdot"), [FakeStory("id2")]]) if "id2" in tag_updater.attributes: raise Exception("Expected id2 to be removed, but it isn't!") self.compare_flags(0) # 7. Getting attributes for non-existent IDs should return empty id2_got = tag_updater.get_attributes("id2") if id2_got != {}: raise Exception( "Expected non-existent id to return empty! Got %s" % id2_got) self.compare_flags(0) # 8. Getting stories_removed for item still in tag should do nothing call_hook("curses_stories_removed", [FakeTag("maintag:Slashdot"), [FakeStory("id1")]]) if "id1" not in tag_updater.attributes: raise Exception("Expected id1 to remain in attributes!") self.compare_flags(0) # 9. Config adding a tag should create a new tagcore config_backend.inject("NEWTAGS", ["maintag:Test1"]) self.compare_flags(NEW_TC) # 10. Config removing an empty tag should delete a tagcore self.reset_flags() config_backend.inject("DELTAGS", ["maintag:reddit"]) self.compare_flags(DEL_TC) self.compare_var("del_tc", "maintag:reddit") # 11. Config removing an populated tag should delete a tagcore and # cause items_removed. NOTE for now tagcores are never deleted, they # just exist empty self.reset_flags() config_backend.inject("DELTAGS", ["maintag:Slashdot"]) self.compare_flags(DEL_TC | ITEMS_REMOVED) self.compare_var("del_tc", "maintag:Slashdot") self.compare_var("oir_tctag", "maintag:Slashdot") self.compare_var("oir_tcids", ["id1"]) # 12. Update should cause all tags to generate a tag_update # hook call on ITEMS, and update_complete when all done. self.reset_flags() tag_updater.update() tag_backend.inject("ITEMS", {"maintag:Test1": ["id3", "id4"]}) tag_backend.inject("ITEMSDONE", {}) tag_backend.inject("ATTRIBUTES", { "id3": { "test": "test" }, "id4": { "test": "test" } }) print(tag_updater.updating) self.compare_flags(TAG_UPDATED | UPDATE_COMPLETE | ITEMS_ADDED | ATTRIBUTES) self.compare_var("otu_tag", "maintag:Test1") return True
def check(self): version_check_script = { 'VERSION' : { '*' : [('VERSION', 0.1)] } } backend = TestBackend("config", version_check_script) return config.init(backend, CANTO_PROTOCOL_COMPATIBLE) == False
def check(self): script = { "VERSION": {"*": [("VERSION", CANTO_PROTOCOL_COMPATIBLE)]}, "CONFIGS": {"*": [("CONFIGS", {"CantoCurses": config.template_config})]}, } backend = TestBackend("config", script) config.init(backend, CANTO_PROTOCOL_COMPATIBLE) on_hook("curses_tag_opt_change", self.on_tag_opt_change) on_hook("curses_opt_change", self.on_opt_change) on_hook("curses_def_opt_change", self.on_def_opt_change) on_hook("curses_feed_opt_change", self.on_feed_opt_change) on_hook("curses_new_tag", self.on_new_tag) on_hook("curses_del_tag", self.on_del_tag) on_hook("curses_eval_tags_changed", self.on_eval_tags_changed) # 1. Only Opt_change self.reset_flags() test_config = eval(repr(config.template_config)) test_config["browser"]["path"] = "testoption" backend.inject("CONFIGS", {"CantoCurses": test_config}) self.compare_flags(OPT_CHANGE) self.compare_config(config.config, "browser.path", "testoption") # Check that the opt change hook got the smallest possible changeset self.compare_var("oc_opts", {"browser": {"path": "testoption"}}) # 2. Invalid Tag_opt_change self.reset_flags() test_config = {"tags": {"test": eval(repr(config.tag_template_config))}} backend.inject("CONFIGS", test_config) self.compare_flags(0) # 3. NEWTAG (also causes OPT_CHANGE because of tag order being # expanded) Does not cause an EVAL CHANGE because test1 doesn't get # match by the tags setting (i.e. tags starting with maintag:) self.reset_flags() backend.inject("NEWTAGS", ["test1"]) self.compare_flags(NEW_TAG | OPT_CHANGE) self.compare_config(config.config, "tagorder", ["test1"]) self.compare_config(config.vars, "curtags", []) self.compare_var("new_tags", "test1") self.compare_var("oc_opts", {"tagorder": ["test1"]}) # 4. NEWTAG, this time with EVAL because "maintag:Slashdot" does match tags self.reset_flags() backend.inject("NEWTAGS", ["maintag:Slashdot"]) self.compare_flags(NEW_TAG | OPT_CHANGE | EVAL_TAGS) self.compare_config(config.config, "tagorder", ["test1", "maintag:Slashdot"]) self.compare_config(config.vars, "curtags", ["maintag:Slashdot"]) # 5. switch_tags (promote demote) self.reset_flags() # These are fodder backend.inject("NEWTAGS", ["maintag:Test2"]) backend.inject("NEWTAGS", ["maintag:Test3"]) backend.inject("NEWTAGS", ["maintag:Test4"]) self.compare_flags(NEW_TAG | OPT_CHANGE | EVAL_TAGS) self.compare_config( config.config, "tagorder", ["test1", "maintag:Slashdot", "maintag:Test2", "maintag:Test3", "maintag:Test4"] ) self.compare_config( config.vars, "curtags", ["maintag:Slashdot", "maintag:Test2", "maintag:Test3", "maintag:Test4"] ) self.reset_flags() config.switch_tags("maintag:Test2", "maintag:Test3") self.compare_flags(OPT_CHANGE | EVAL_TAGS) self.compare_config( config.config, "tagorder", ["test1", "maintag:Slashdot", "maintag:Test3", "maintag:Test2", "maintag:Test4"] ) self.compare_config( config.vars, "curtags", ["maintag:Slashdot", "maintag:Test3", "maintag:Test2", "maintag:Test4"] ) self.compare_var( "oc_opts", {"tagorder": ["test1", "maintag:Slashdot", "maintag:Test3", "maintag:Test2", "maintag:Test4"]} ) # 6. DELTAG self.reset_flags() backend.inject("DELTAGS", ["maintag:Test4"]) self.compare_flags(DEL_TAG | OPT_CHANGE | EVAL_TAGS) self.compare_config(config.config, "tagorder", ["test1", "maintag:Slashdot", "maintag:Test3", "maintag:Test2"]) self.compare_config(config.vars, "curtags", ["maintag:Slashdot", "maintag:Test3", "maintag:Test2"]) self.compare_var("del_tags", "maintag:Test4") # 7. Changing the tags regex self.reset_flags() # More fodder backend.inject("NEWTAGS", ["alt:t1"]) backend.inject("NEWTAGS", ["alt:t2"]) backend.inject("NEWTAGS", ["alt:t3"]) self.compare_flags(NEW_TAG | OPT_CHANGE) self.compare_config( config.config, "tagorder", ["test1", "maintag:Slashdot", "maintag:Test3", "maintag:Test2", "alt:t1", "alt:t2", "alt:t3"], ) self.compare_config(config.vars, "curtags", ["maintag:Slashdot", "maintag:Test3", "maintag:Test2"]) self.reset_flags() c = config.get_conf() c["tags"] = "alt:.*" config.set_conf(c) self.compare_flags(OPT_CHANGE | EVAL_TAGS) return True
def check(self): script = { 'VERSION': { '*': [('VERSION', CANTO_PROTOCOL_COMPATIBLE)] }, 'CONFIGS': { '*': [('CONFIGS', { "CantoCurses": config.template_config })] }, } backend = TestBackend("config", script) config.init(backend, CANTO_PROTOCOL_COMPATIBLE) on_hook("curses_tag_opt_change", self.on_tag_opt_change) on_hook("curses_opt_change", self.on_opt_change) on_hook("curses_def_opt_change", self.on_def_opt_change) on_hook("curses_feed_opt_change", self.on_feed_opt_change) on_hook("curses_new_tag", self.on_new_tag) on_hook("curses_del_tag", self.on_del_tag) on_hook("curses_eval_tags_changed", self.on_eval_tags_changed) # 1. Only Opt_change self.reset_flags() test_config = eval(repr(config.template_config)) test_config["browser"]["path"] = "testoption" backend.inject("CONFIGS", {"CantoCurses": test_config}) self.compare_flags(OPT_CHANGE) self.compare_config(config.config, "browser.path", "testoption") # Check that the opt change hook got the smallest possible changeset self.compare_var("oc_opts", {"browser": {"path": "testoption"}}) # 2. Invalid Tag_opt_change self.reset_flags() test_config = { "tags": { "test": eval(repr(config.tag_template_config)) } } backend.inject("CONFIGS", test_config) self.compare_flags(0) # 3. NEWTAG (also causes OPT_CHANGE because of tag order being # expanded) Does not cause an EVAL CHANGE because test1 doesn't get # match by the tags setting (i.e. tags starting with maintag:) self.reset_flags() backend.inject("NEWTAGS", ["test1"]) self.compare_flags(NEW_TAG | OPT_CHANGE) self.compare_config(config.config, "tagorder", ["test1"]) self.compare_config(config.vars, "curtags", []) self.compare_var("new_tags", "test1") self.compare_var("oc_opts", {"tagorder": ["test1"]}) # 4. NEWTAG, this time with EVAL because "maintag:Slashdot" does match tags self.reset_flags() backend.inject("NEWTAGS", ["maintag:Slashdot"]) self.compare_flags(NEW_TAG | OPT_CHANGE | EVAL_TAGS) self.compare_config(config.config, "tagorder", ["test1", "maintag:Slashdot"]) self.compare_config(config.vars, "curtags", ["maintag:Slashdot"]) # 5. switch_tags (promote demote) self.reset_flags() # These are fodder backend.inject("NEWTAGS", ["maintag:Test2"]) backend.inject("NEWTAGS", ["maintag:Test3"]) backend.inject("NEWTAGS", ["maintag:Test4"]) self.compare_flags(NEW_TAG | OPT_CHANGE | EVAL_TAGS) self.compare_config(config.config, "tagorder", [ "test1", "maintag:Slashdot", "maintag:Test2", "maintag:Test3", "maintag:Test4" ]) self.compare_config(config.vars, "curtags", [ "maintag:Slashdot", "maintag:Test2", "maintag:Test3", "maintag:Test4" ]) self.reset_flags() config.switch_tags("maintag:Test2", "maintag:Test3") self.compare_flags(OPT_CHANGE | EVAL_TAGS) self.compare_config(config.config, "tagorder", [ "test1", "maintag:Slashdot", "maintag:Test3", "maintag:Test2", "maintag:Test4" ]) self.compare_config(config.vars, "curtags", [ "maintag:Slashdot", "maintag:Test3", "maintag:Test2", "maintag:Test4" ]) self.compare_var( "oc_opts", { "tagorder": [ "test1", "maintag:Slashdot", "maintag:Test3", "maintag:Test2", "maintag:Test4" ] }) # 6. DELTAG self.reset_flags() backend.inject("DELTAGS", ["maintag:Test4"]) self.compare_flags(DEL_TAG | OPT_CHANGE | EVAL_TAGS) self.compare_config( config.config, "tagorder", ["test1", "maintag:Slashdot", "maintag:Test3", "maintag:Test2"]) self.compare_config( config.vars, "curtags", ["maintag:Slashdot", "maintag:Test3", "maintag:Test2"]) self.compare_var("del_tags", "maintag:Test4") # 7. Changing the tags regex self.reset_flags() # More fodder backend.inject("NEWTAGS", ["alt:t1"]) backend.inject("NEWTAGS", ["alt:t2"]) backend.inject("NEWTAGS", ["alt:t3"]) self.compare_flags(NEW_TAG | OPT_CHANGE) self.compare_config(config.config, "tagorder", [ "test1", "maintag:Slashdot", "maintag:Test3", "maintag:Test2", "alt:t1", "alt:t2", "alt:t3" ]) self.compare_config( config.vars, "curtags", ["maintag:Slashdot", "maintag:Test3", "maintag:Test2"]) self.reset_flags() c = config.get_conf() c["tags"] = "alt:.*" config.set_conf(c) self.compare_flags(OPT_CHANGE | EVAL_TAGS) return True