.. _RefGrammarListDocTests: Doctests for the List class **************************************************************************** List and ListRef element classes ============================================================================ Basic usage ---------------------------------------------------------------------------- Setup test tooling:: >>> from dragonfly import * >>> from dragonfly.test import ElementTester >>> list_fruit = List("list_fruit") >>> element = Sequence([Literal("item"), ListRef("list_fruit_ref", list_fruit)]) >>> tester_fruit = ElementTester(element) >>> # Explicitly load tester grammar because lists can only be updated >>> # for loaded grammars. >>> tester_fruit.load() Empty lists cannot be recognized:: >>> tester_fruit.recognize("item") RecognitionFailure >>> tester_fruit.recognize("item apple") RecognitionFailure A list update is automatically available for recognition without reloading the grammar:: >>> tester_fruit.recognize("item apple") RecognitionFailure >>> list_fruit.append("apple") >>> list_fruit ['apple'] >>> tester_fruit.recognize("item apple") [u'item', u'apple'] >>> tester_fruit.recognize("item banana") RecognitionFailure >>> list_fruit.append("banana") >>> list_fruit ['apple', 'banana'] >>> tester_fruit.recognize("item apple") [u'item', u'apple'] >>> tester_fruit.recognize("item banana") [u'item', u'banana'] >>> tester_fruit.recognize("item apple banana") RecognitionFailure >>> list_fruit.remove("apple") >>> list_fruit ['banana'] >>> tester_fruit.recognize("item apple") RecognitionFailure >>> tester_fruit.recognize("item banana") [u'item', u'banana'] Lists can contain the same value multiple times, although that does not affect recognition:: >>> list_fruit.append("banana") >>> list_fruit ['banana', 'banana'] >>> tester_fruit.recognize("item banana") [u'item', u'banana'] >>> tester_fruit.recognize("item banana banana") RecognitionFailure Tear down test tooling:: >>> # Explicitly unload tester grammar. >>> tester_fruit.unload() Multiple lists ---------------------------------------------------------------------------- Setup test tooling:: >>> list_meat = List("list_meat") >>> list_veg = List("list_veg") >>> element = Sequence([Literal("food"), ... ListRef("list_meat_ref", list_meat), ... ListRef("list_veg_ref", list_veg)]) >>> tester_meat_veg = ElementTester(element) >>> # Explicitly load tester grammar because lists can only be updated >>> # for loaded grammars. >>> tester_meat_veg.load() Multiple lists can be combined within a single rule:: >>> list_meat.append("steak") >>> tester_meat_veg.recognize("food steak") RecognitionFailure >>> list_veg.append("carrot") >>> tester_meat_veg.recognize("food steak carrot") [u'food', u'steak', u'carrot'] >>> list_meat.append("hamburger") >>> tester_meat_veg.recognize("food hamburger carrot") [u'food', u'hamburger', u'carrot'] Tear down test tooling:: >>> # Explicitly unload tester grammar. >>> tester_meat_veg.unload() A single list can be present multiple times within a rule:: >>> element = Sequence([Literal("carnivore"), ... ListRef("list_meat_ref1", list_meat), ... ListRef("list_meat_ref2", list_meat)]) >>> tester_carnivore = ElementTester(element) >>> # Explicitly load tester grammar because lists can only be updated >>> # for loaded grammars. >>> tester_carnivore.load() >>> tester_carnivore.recognize("carnivore steak") RecognitionFailure >>> tester_carnivore.recognize("carnivore hamburger steak") [u'carnivore', u'hamburger', u'steak'] >>> tester_carnivore.recognize("carnivore steak hamburger") [u'carnivore', u'steak', u'hamburger'] >>> tester_carnivore.recognize("carnivore steak steak") [u'carnivore', u'steak', u'steak'] >>> list_meat.remove("steak") >>> tester_carnivore.recognize("carnivore steak hamburger") RecognitionFailure >>> tester_carnivore.recognize("carnivore hamburger hamburger") [u'carnivore', u'hamburger', u'hamburger'] Tear down test tooling:: >>> # Explicitly unload tester grammar. >>> tester_carnivore.unload() Unique list names ---------------------------------------------------------------------------- The names of lists must be unique within a grammar:: >>> list_fruit1 = List("list_fruit") >>> list_fruit2 = List("list_fruit") >>> element = Sequence([Literal("fruit"), ... ListRef("list_fruit1_ref", list_fruit1), ... ListRef("list_fruit2_ref", list_fruit2)]) >>> tester_fruit = ElementTester(element) >>> # Explicitly load tester grammar because lists can only be updated >>> # for loaded grammars. >>> tester_fruit.load() Traceback (most recent call last): ... GrammarError: Two lists with the same name 'list_fruit' not allowed. List add/remove restrictions ---------------------------------------------------------------------------- Setup test tooling:: >>> list_fruit = List("list_fruit", ["apple", "banana"]) >>> element = Sequence([Literal("item"), ListRef("list_fruit_ref", list_fruit)]) >>> tester_fruit = ElementTester(element) >>> # Explicitly load tester grammar because lists can only be updated >>> # for loaded grammars. >>> tester_fruit.load() Lists cannot be added while the grammar is loaded:: >>> list_other = List("list_other", ["other"]) >>> tester_fruit.add_list(list_other) # Fails. Traceback (most recent call last): ... GrammarError: Cannot add list while loaded. Lists cannot be removed while the grammar is loaded:: >>> tester_fruit.remove_list(list_fruit) # Fails. Traceback (most recent call last): ... GrammarError: Cannot remove list while loaded. Tear down test tooling:: >>> # Explicitly unload tester grammar. >>> tester_fruit.unload() ListRef construction ---------------------------------------------------------------------------- ListRef objects must be created referencing the correct type of list object:: >>> print(ListRef("list_fruit_ref", [])) # Fails. Traceback (most recent call last): ... TypeError: List argument to ListRef constructor must be a Dragonfly list. >>> print(ListRef("list_fruit_ref", List("list_fruit"))) # Succeeds. ListRef('list_fruit') List context manager ---------------------------------------------------------------------------- List operations can be performed optimally via Python's ``with`` statement:: >>> list_fruit = List("list_fruit") >>> element = Sequence([Literal("item"), ListRef("list_fruit_ref", list_fruit)]) >>> tester_fruit = ElementTester(element) >>> tester_fruit.load() >>> with list_fruit: ... list_fruit.append("apple") ... list_fruit.append("banana") ... >>> list_fruit ['apple', 'banana'] >>> tester_fruit.recognize("item apple") [u'item', u'apple'] >>> tester_fruit.recognize("item banana") [u'item', u'banana'] Tear down test tooling:: >>> # Explicitly unload tester grammar. >>> tester_fruit.unload()