def testCoreProject_NewRoot(fncDir, outDir, refDir, mockGUI): """Check that new root folders can be added to the project. """ projFile = os.path.join(fncDir, "nwProject.nwx") testFile = os.path.join(outDir, "coreProject_NewRoot_nwProject.nwx") compFile = os.path.join(refDir, "coreProject_NewRoot_nwProject.nwx") theProject = NWProject(mockGUI) theProject.projTree.setSeed(42) assert theProject.newProject({"projPath": fncDir}) is True assert theProject.setProjectPath(fncDir) is True assert theProject.saveProject() is True assert theProject.closeProject() is True assert theProject.openProject(projFile) is True assert isinstance(theProject.newRoot("Novel", nwItemClass.NOVEL), type(None)) assert isinstance(theProject.newRoot("Plot", nwItemClass.PLOT), type(None)) assert isinstance(theProject.newRoot("Character", nwItemClass.CHARACTER), type(None)) assert isinstance(theProject.newRoot("World", nwItemClass.WORLD), type(None)) assert isinstance(theProject.newRoot("Timeline", nwItemClass.TIMELINE), str) assert isinstance(theProject.newRoot("Object", nwItemClass.OBJECT), str) assert isinstance(theProject.newRoot("Custom1", nwItemClass.CUSTOM), str) assert isinstance(theProject.newRoot("Custom2", nwItemClass.CUSTOM), str) assert theProject.projChanged is True assert theProject.saveProject() is True assert theProject.closeProject() is True copyfile(projFile, testFile) assert cmpFiles(testFile, compFile, [2, 6, 7, 8]) assert theProject.projChanged is False
def testCoreIndex_ScanText(nwMinimal, mockGUI): """Check the index text scanner. """ theProject = NWProject(mockGUI) theProject.projTree.setSeed(42) assert theProject.openProject(nwMinimal) is True theIndex = NWIndex(theProject) # Some items for fail to scan tests dHandle = theProject.newFolder("Folder", nwItemClass.NOVEL, "a508bb932959c") xHandle = theProject.newFile("No Layout", nwItemClass.NOVEL, "a508bb932959c") xItem = theProject.projTree[xHandle] xItem.setLayout(nwItemLayout.NO_LAYOUT) # Check invalid data assert theIndex.scanText(None, "Hello World!") is False assert theIndex.scanText(dHandle, "Hello World!") is False assert theIndex.scanText(xHandle, "Hello World!") is False xItem.setLayout(nwItemLayout.DOCUMENT) xItem.setParent(None) assert theIndex.scanText(xHandle, "Hello World!") is False # Create the trash folder tHandle = theProject.trashFolder() assert theProject.projTree[tHandle] is not None xItem.setParent(tHandle) assert theIndex.scanText(xHandle, "Hello World!") is False # Create the archive root aHandle = theProject.newRoot("Archive", nwItemClass.ARCHIVE) assert theProject.projTree[aHandle] is not None xItem.setParent(aHandle) assert theIndex.scanText(xHandle, "Hello World!") is False # Make some usable items tHandle = theProject.newFile("Title", nwItemClass.NOVEL, "a508bb932959c") pHandle = theProject.newFile("Page", nwItemClass.NOVEL, "a508bb932959c") nHandle = theProject.newFile("Hello", nwItemClass.NOVEL, "a508bb932959c") cHandle = theProject.newFile("Jane", nwItemClass.CHARACTER, "afb3043c7b2b3") sHandle = theProject.newFile("Scene", nwItemClass.NOVEL, "a508bb932959c") # Text Indexing # ============= # Index correct text assert theIndex.scanText(cHandle, ("# Jane Smith\n" "@tag: Jane\n")) assert theIndex.scanText(nHandle, ("# Hello World!\n" "@pov: Jane\n" "@char: Jane\n\n" "% this is a comment\n\n" "This is a story about Jane Smith.\n\n" "Well, not really.\n")) assert theIndex._tagIndex == {"Jane": [2, cHandle, "CHARACTER", "T000001"]} assert theIndex.getNovelData(nHandle, "T000001")["title"] == "Hello World!" # Title Indexing # ============== # Document File assert theIndex.scanText( nHandle, ( "# Title One\n\n" "% synopsis: Synopsis One.\n\n" "Paragraph One.\n\n" "## Title Two\n\n" "% synopsis: Synopsis Two.\n\n" "Paragraph Two.\n\n" "### Title Three\n\n" "% synopsis: Synopsis Three.\n\n" "Paragraph Three.\n\n" "#### Title Four\n\n" "% synopsis: Synopsis Four.\n\n" "Paragraph Four.\n\n" "##### Title Five\n\n" # Not interpreted as a title, the hashes are counted as a word "Paragraph Five.\n\n")) assert nHandle not in theIndex._refIndex assert theIndex._fileIndex[nHandle]["T000001"]["level"] == "H1" assert theIndex._fileIndex[nHandle]["T000007"]["level"] == "H2" assert theIndex._fileIndex[nHandle]["T000013"]["level"] == "H3" assert theIndex._fileIndex[nHandle]["T000019"]["level"] == "H4" assert theIndex._fileIndex[nHandle]["T000001"]["title"] == "Title One" assert theIndex._fileIndex[nHandle]["T000007"]["title"] == "Title Two" assert theIndex._fileIndex[nHandle]["T000013"]["title"] == "Title Three" assert theIndex._fileIndex[nHandle]["T000019"]["title"] == "Title Four" assert theIndex._fileIndex[nHandle]["T000001"]["layout"] == "DOCUMENT" assert theIndex._fileIndex[nHandle]["T000007"]["layout"] == "DOCUMENT" assert theIndex._fileIndex[nHandle]["T000013"]["layout"] == "DOCUMENT" assert theIndex._fileIndex[nHandle]["T000019"]["layout"] == "DOCUMENT" assert theIndex._fileIndex[nHandle]["T000001"]["cCount"] == 23 assert theIndex._fileIndex[nHandle]["T000007"]["cCount"] == 23 assert theIndex._fileIndex[nHandle]["T000013"]["cCount"] == 27 assert theIndex._fileIndex[nHandle]["T000019"]["cCount"] == 56 assert theIndex._fileIndex[nHandle]["T000001"]["wCount"] == 4 assert theIndex._fileIndex[nHandle]["T000007"]["wCount"] == 4 assert theIndex._fileIndex[nHandle]["T000013"]["wCount"] == 4 assert theIndex._fileIndex[nHandle]["T000019"]["wCount"] == 9 assert theIndex._fileIndex[nHandle]["T000001"]["pCount"] == 1 assert theIndex._fileIndex[nHandle]["T000007"]["pCount"] == 1 assert theIndex._fileIndex[nHandle]["T000013"]["pCount"] == 1 assert theIndex._fileIndex[nHandle]["T000019"]["pCount"] == 3 assert theIndex._fileIndex[nHandle]["T000001"][ "synopsis"] == "Synopsis One." assert theIndex._fileIndex[nHandle]["T000007"][ "synopsis"] == "Synopsis Two." assert theIndex._fileIndex[nHandle]["T000013"][ "synopsis"] == "Synopsis Three." assert theIndex._fileIndex[nHandle]["T000019"][ "synopsis"] == "Synopsis Four." # Note File assert theIndex.scanText(cHandle, ("# Title One\n\n" "@tag: One\n\n" "% synopsis: Synopsis One.\n\n" "Paragraph One.\n\n")) assert cHandle not in theIndex._refIndex assert theIndex._fileIndex[cHandle]["T000001"]["level"] == "H1" assert theIndex._fileIndex[cHandle]["T000001"]["title"] == "Title One" assert theIndex._fileIndex[cHandle]["T000001"]["layout"] == "NOTE" assert theIndex._fileIndex[cHandle]["T000001"]["cCount"] == 23 assert theIndex._fileIndex[cHandle]["T000001"]["wCount"] == 4 assert theIndex._fileIndex[cHandle]["T000001"]["pCount"] == 1 assert theIndex._fileIndex[cHandle]["T000001"][ "synopsis"] == "Synopsis One." # Valid and Invalid References assert theIndex.scanText( sHandle, ( "# Title One\n\n" "@pov: One\n\n" # Valid "@char: Two\n\n" # Invalid tag "@:\n\n" # Invalid line "% synopsis: Synopsis One.\n\n" "Paragraph One.\n\n")) assert theIndex._refIndex[sHandle]["T000001"] == ([[3, "@pov", "One"], [5, "@char", "Two"]]) # Special Titles # ============== assert theIndex.scanText(tHandle, ("#! My Project\n\n" ">> By Jane Doe <<\n\n")) assert tHandle not in theIndex._refIndex assert theIndex._fileIndex[tHandle]["T000001"]["level"] == "H1" assert theIndex._fileIndex[tHandle]["T000001"]["title"] == "My Project" assert theIndex._fileIndex[tHandle]["T000001"]["layout"] == "DOCUMENT" assert theIndex._fileIndex[tHandle]["T000001"]["cCount"] == 21 assert theIndex._fileIndex[tHandle]["T000001"]["wCount"] == 5 assert theIndex._fileIndex[tHandle]["T000001"]["pCount"] == 1 assert theIndex._fileIndex[tHandle]["T000001"]["synopsis"] == "" assert theIndex.scanText(tHandle, ("##! Prologue\n\n" "In the beginning there was time ...\n\n")) assert tHandle not in theIndex._refIndex assert theIndex._fileIndex[tHandle]["T000001"]["level"] == "H2" assert theIndex._fileIndex[tHandle]["T000001"]["title"] == "Prologue" assert theIndex._fileIndex[tHandle]["T000001"]["layout"] == "DOCUMENT" assert theIndex._fileIndex[tHandle]["T000001"]["cCount"] == 43 assert theIndex._fileIndex[tHandle]["T000001"]["wCount"] == 8 assert theIndex._fileIndex[tHandle]["T000001"]["pCount"] == 1 assert theIndex._fileIndex[tHandle]["T000001"]["synopsis"] == "" # Page wo/Title # ============= theProject.projTree[pHandle]._layout = nwItemLayout.DOCUMENT assert theIndex.scanText(pHandle, ("This is a page with some text on it.\n\n")) assert pHandle in theIndex._fileIndex assert theIndex._fileIndex[pHandle]["T000000"]["level"] == "H0" assert theIndex._fileIndex[pHandle]["T000000"]["title"] == "" assert theIndex._fileIndex[pHandle]["T000000"]["layout"] == "DOCUMENT" assert theIndex._fileIndex[pHandle]["T000000"]["cCount"] == 36 assert theIndex._fileIndex[pHandle]["T000000"]["wCount"] == 9 assert theIndex._fileIndex[pHandle]["T000000"]["pCount"] == 1 assert theIndex._fileIndex[pHandle]["T000000"]["synopsis"] == "" theProject.projTree[pHandle]._layout = nwItemLayout.NOTE assert theIndex.scanText(pHandle, ("This is a page with some text on it.\n\n")) assert pHandle in theIndex._fileIndex assert theIndex._fileIndex[pHandle]["T000000"]["level"] == "H0" assert theIndex._fileIndex[pHandle]["T000000"]["title"] == "" assert theIndex._fileIndex[pHandle]["T000000"]["layout"] == "NOTE" assert theIndex._fileIndex[pHandle]["T000000"]["cCount"] == 36 assert theIndex._fileIndex[pHandle]["T000000"]["wCount"] == 9 assert theIndex._fileIndex[pHandle]["T000000"]["pCount"] == 1 assert theIndex._fileIndex[pHandle]["T000000"]["synopsis"] == "" assert theProject.closeProject() is True
def testCoreIndex_ItemIndex(mockGUI, fncDir, mockRnd): """Check the ItemIndex class. """ theProject = NWProject(mockGUI) buildTestProject(theProject, fncDir) nHandle = "0000000000014" cHandle = "0000000000016" sHandle = "0000000000017" assert theProject.index.saveIndex() is True itemIndex = theProject.index._itemIndex # The index should be empty assert nHandle not in itemIndex assert cHandle not in itemIndex assert sHandle not in itemIndex # Add Items # ========= assert cHandle not in itemIndex # Add the novel chapter file itemIndex.add(cHandle, theProject.tree[cHandle]) assert cHandle in itemIndex assert itemIndex[cHandle].item == theProject.tree[cHandle] assert itemIndex.mainItemHeader(cHandle) == "H0" assert itemIndex.allItemTags(cHandle) == [] assert list(itemIndex.iterItemHeaders(cHandle))[0][0] == "T000000" # Add a heading to the item, which should replace the T000000 heading itemIndex.addItemHeading(cHandle, "T000001", "H2", "Chapter One") assert itemIndex.mainItemHeader(cHandle) == "H2" assert list(itemIndex.iterItemHeaders(cHandle))[0][0] == "T000001" # Set the remainig data values itemIndex.setHeadingCounts(cHandle, "T000001", 60, 10, 2) itemIndex.setHeadingSynopsis(cHandle, "T000001", "In the beginning ...") itemIndex.setHeadingTag(cHandle, "T000001", "One") itemIndex.addHeadingReferences(cHandle, "T000001", ["Jane"], "@pov") itemIndex.addHeadingReferences(cHandle, "T000001", ["Jane"], "@focus") itemIndex.addHeadingReferences(cHandle, "T000001", ["Jane", "John"], "@char") idxData = itemIndex.packData() assert idxData[cHandle]["level"] == "H2" assert idxData[cHandle]["headings"]["T000001"] == { "level": "H2", "title": "Chapter One", "tag": "One", "cCount": 60, "wCount": 10, "pCount": 2, "synopsis": "In the beginning ...", } assert "@pov" in idxData[cHandle]["references"]["T000001"]["Jane"] assert "@focus" in idxData[cHandle]["references"]["T000001"]["Jane"] assert "@char" in idxData[cHandle]["references"]["T000001"]["Jane"] assert "@char" in idxData[cHandle]["references"]["T000001"]["John"] # Add the other two files itemIndex.add(nHandle, theProject.tree[nHandle]) itemIndex.add(sHandle, theProject.tree[sHandle]) itemIndex.addItemHeading(nHandle, "T000001", "H1", "Novel") itemIndex.addItemHeading(sHandle, "T000001", "H3", "Scene One") # Check Item and Heading Direct Access # ==================================== # Check repr strings assert repr(itemIndex[nHandle]) == f"<IndexItem handle='{nHandle}'>" assert repr( itemIndex[nHandle]["T000001"]) == "<IndexHeading key='T000001'>" # Check content of a single item assert "T000001" in itemIndex[nHandle] assert itemIndex[cHandle].allTags() == ["One"] # Check the content of a single heading assert itemIndex[cHandle]["T000001"].key == "T000001" assert itemIndex[cHandle]["T000001"].level == "H2" assert itemIndex[cHandle]["T000001"].title == "Chapter One" assert itemIndex[cHandle]["T000001"].tag == "One" assert itemIndex[cHandle]["T000001"].charCount == 60 assert itemIndex[cHandle]["T000001"].wordCount == 10 assert itemIndex[cHandle]["T000001"].paraCount == 2 assert itemIndex[cHandle]["T000001"].synopsis == "In the beginning ..." assert "Jane" in itemIndex[cHandle]["T000001"].references assert "John" in itemIndex[cHandle]["T000001"].references # Check heading level setter itemIndex[cHandle]["T000001"].setLevel("H3") # Change it assert itemIndex[cHandle]["T000001"].level == "H3" itemIndex[cHandle]["T000001"].setLevel("H2") # Set it back assert itemIndex[cHandle]["T000001"].level == "H2" itemIndex[cHandle]["T000001"].setLevel("H5") # Invalid level assert itemIndex[cHandle]["T000001"].level == "H2" # Data Extraction # =============== # Get headers allHeads = list(itemIndex.iterAllHeaders()) assert allHeads[0][0] == cHandle assert allHeads[1][0] == nHandle assert allHeads[2][0] == sHandle assert allHeads[0][1] == "T000001" assert allHeads[1][1] == "T000001" assert allHeads[2][1] == "T000001" # Ask for stuff that doesn't exist assert itemIndex.mainItemHeader("blablabla") == "H0" assert itemIndex.allItemTags("blablabla") == [] # Novel Structure # =============== # Add a second novel mHandle = theProject.newRoot(nwItemClass.NOVEL) uHandle = theProject.newFile("Title Page", mHandle) itemIndex.add(uHandle, theProject.tree[uHandle]) itemIndex.addItemHeading(uHandle, "T000001", "H1", "Novel 2") assert uHandle in itemIndex # Structure of all novels nStruct = list(itemIndex.iterNovelStructure()) assert len(nStruct) == 4 assert nStruct[0][0] == nHandle assert nStruct[1][0] == cHandle assert nStruct[2][0] == sHandle assert nStruct[3][0] == uHandle # Novel structure with root handle set nStruct = list(itemIndex.iterNovelStructure(rootHandle="0000000000010")) assert len(nStruct) == 3 assert nStruct[0][0] == nHandle assert nStruct[1][0] == cHandle assert nStruct[2][0] == sHandle nStruct = list(itemIndex.iterNovelStructure(rootHandle=mHandle)) assert len(nStruct) == 1 assert nStruct[0][0] == uHandle # Inject garbage into tree theProject.tree._treeOrder.append("stuff") nStruct = list(itemIndex.iterNovelStructure()) assert len(nStruct) == 4 assert nStruct[0][0] == nHandle assert nStruct[1][0] == cHandle assert nStruct[2][0] == sHandle assert nStruct[3][0] == uHandle # Skip excluded theProject.tree[sHandle].setExported(False) nStruct = list(itemIndex.iterNovelStructure(skipExcl=True)) assert len(nStruct) == 3 assert nStruct[0][0] == nHandle assert nStruct[1][0] == cHandle assert nStruct[2][0] == uHandle # Delete new item del itemIndex[uHandle] assert uHandle not in itemIndex # Unpack Error Handling # ===================== # Pack/unpack should restore state content = itemIndex.packData() itemIndex.clear() itemIndex.unpackData(content) assert itemIndex.packData() == content itemIndex.clear() # Data must be dictionary with pytest.raises(ValueError): itemIndex.unpackData("stuff") # Keys must be valid handles with pytest.raises(ValueError): itemIndex.unpackData({"stuff": "more stuff"}) # Unknown keys should be skipped itemIndex.unpackData({"0000000000000": {}}) assert itemIndex._items == {} # Known keys can be added, even witout data itemIndex.unpackData({nHandle: {}}) assert nHandle in itemIndex # Title tags must be valid with pytest.raises(ValueError): itemIndex.unpackData({cHandle: {"headings": {"TTTTTTT": {}}}}) # Reference without a heading should be rejected itemIndex.unpackData({ cHandle: { "headings": { "T000001": {} }, "references": { "T000001": {}, "T000002": {} }, } }) assert "T000001" in itemIndex[cHandle] assert "T000002" not in itemIndex[cHandle] itemIndex.clear() # Tag keys must be strings with pytest.raises(ValueError): itemIndex.unpackData({ cHandle: { "headings": { "T000001": {} }, "references": { "T000001": { 1234: "@pov" } }, } }) # Type must be strings with pytest.raises(ValueError): itemIndex.unpackData({ cHandle: { "headings": { "T000001": {} }, "references": { "T000001": { "John": [] } }, } }) # Types must be valid with pytest.raises(ValueError): itemIndex.unpackData({ cHandle: { "headings": { "T000001": {} }, "references": { "T000001": { "John": "@pov,@char,@stuff" } }, } }) # This should pass itemIndex.unpackData({ cHandle: { "headings": { "T000001": {} }, "references": { "T000001": { "John": "@pov,@char" } }, } })
def testCoreIndex_ScanText(mockGUI, fncDir, mockRnd): """Check the index text scanner. """ theProject = NWProject(mockGUI) buildTestProject(theProject, fncDir) theIndex = theProject.index # Some items for fail to scan tests dHandle = theProject.newFolder("Folder", "0000000000010") xHandle = theProject.newFile("No Layout", "0000000000010") xItem = theProject.tree[xHandle] xItem.setLayout(nwItemLayout.NO_LAYOUT) # Check invalid data assert theIndex.scanText(None, "Hello World!") is False assert theIndex.scanText(dHandle, "Hello World!") is False assert theIndex.scanText(xHandle, "Hello World!") is False xItem.setLayout(nwItemLayout.DOCUMENT) xItem.setParent(None) assert theIndex.scanText(xHandle, "Hello World!") is False # Create the trash folder tHandle = theProject.trashFolder() assert theProject.tree[tHandle] is not None xItem.setParent(tHandle) theProject.tree.updateItemData(xItem.itemHandle) assert xItem.itemRoot == tHandle assert xItem.itemClass == nwItemClass.TRASH assert theIndex.scanText(xHandle, "Hello World!") is False # Create the archive root aHandle = theProject.newRoot(nwItemClass.ARCHIVE) assert theProject.tree[aHandle] is not None xItem.setParent(aHandle) theProject.tree.updateItemData(xItem.itemHandle) assert theIndex.scanText(xHandle, "Hello World!") is False # Make some usable items tHandle = theProject.newFile("Title", "0000000000010") pHandle = theProject.newFile("Page", "0000000000010") nHandle = theProject.newFile("Hello", "0000000000010") cHandle = theProject.newFile("Jane", "0000000000012") sHandle = theProject.newFile("Scene", "0000000000010") # Text Indexing # ============= # Index correct text assert theIndex.scanText(cHandle, ("# Jane Smith\n" "@tag: Jane\n")) assert theIndex.scanText(nHandle, ("# Hello World!\n" "@pov: Jane\n" "@char: Jane\n\n" "% this is a comment\n\n" "This is a story about Jane Smith.\n\n" "Well, not really.\n")) assert theIndex._tagsIndex.tagHandle("Jane") == cHandle assert theIndex._tagsIndex.tagHeading("Jane") == "T000001" assert theIndex._tagsIndex.tagClass("Jane") == "CHARACTER" assert theIndex.getNovelData(nHandle, "T000001").title == "Hello World!" # Title Indexing # ============== # Document File assert theIndex.scanText( nHandle, ( "# Title One\n\n" "% synopsis: Synopsis One.\n\n" "Paragraph One.\n\n" "## Title Two\n\n" "% synopsis: Synopsis Two.\n\n" "Paragraph Two.\n\n" "### Title Three\n\n" "% synopsis: Synopsis Three.\n\n" "Paragraph Three.\n\n" "#### Title Four\n\n" "% synopsis: Synopsis Four.\n\n" "Paragraph Four.\n\n" "##### Title Five\n\n" # Not interpreted as a title, the hashes are counted as a word "Paragraph Five.\n\n")) assert theIndex._itemIndex[nHandle]["T000001"].references == {} assert theIndex._itemIndex[nHandle]["T000007"].references == {} assert theIndex._itemIndex[nHandle]["T000013"].references == {} assert theIndex._itemIndex[nHandle]["T000019"].references == {} assert theIndex._itemIndex[nHandle]["T000001"].level == "H1" assert theIndex._itemIndex[nHandle]["T000007"].level == "H2" assert theIndex._itemIndex[nHandle]["T000013"].level == "H3" assert theIndex._itemIndex[nHandle]["T000019"].level == "H4" assert theIndex._itemIndex[nHandle]["T000001"].title == "Title One" assert theIndex._itemIndex[nHandle]["T000007"].title == "Title Two" assert theIndex._itemIndex[nHandle]["T000013"].title == "Title Three" assert theIndex._itemIndex[nHandle]["T000019"].title == "Title Four" assert theIndex._itemIndex[nHandle]["T000001"].charCount == 23 assert theIndex._itemIndex[nHandle]["T000007"].charCount == 23 assert theIndex._itemIndex[nHandle]["T000013"].charCount == 27 assert theIndex._itemIndex[nHandle]["T000019"].charCount == 56 assert theIndex._itemIndex[nHandle]["T000001"].wordCount == 4 assert theIndex._itemIndex[nHandle]["T000007"].wordCount == 4 assert theIndex._itemIndex[nHandle]["T000013"].wordCount == 4 assert theIndex._itemIndex[nHandle]["T000019"].wordCount == 9 assert theIndex._itemIndex[nHandle]["T000001"].paraCount == 1 assert theIndex._itemIndex[nHandle]["T000007"].paraCount == 1 assert theIndex._itemIndex[nHandle]["T000013"].paraCount == 1 assert theIndex._itemIndex[nHandle]["T000019"].paraCount == 3 assert theIndex._itemIndex[nHandle]["T000001"].synopsis == "Synopsis One." assert theIndex._itemIndex[nHandle]["T000007"].synopsis == "Synopsis Two." assert theIndex._itemIndex[nHandle][ "T000013"].synopsis == "Synopsis Three." assert theIndex._itemIndex[nHandle]["T000019"].synopsis == "Synopsis Four." # Note File assert theIndex.scanText(cHandle, ("# Title One\n\n" "@tag: One\n\n" "% synopsis: Synopsis One.\n\n" "Paragraph One.\n\n")) assert theIndex._itemIndex[cHandle]["T000001"].references == {} assert theIndex._itemIndex[cHandle]["T000001"].level == "H1" assert theIndex._itemIndex[cHandle]["T000001"].title == "Title One" assert theIndex._itemIndex[cHandle]["T000001"].charCount == 23 assert theIndex._itemIndex[cHandle]["T000001"].wordCount == 4 assert theIndex._itemIndex[cHandle]["T000001"].paraCount == 1 assert theIndex._itemIndex[cHandle]["T000001"].synopsis == "Synopsis One." # Valid and Invalid References assert theIndex.scanText( sHandle, ( "# Title One\n\n" "@pov: One\n\n" # Valid "@char: Two\n\n" # Invalid tag "@:\n\n" # Invalid line "% synopsis: Synopsis One.\n\n" "Paragraph One.\n\n")) assert theIndex._itemIndex[sHandle]["T000001"].references == { "One": {"@pov"}, "Two": {"@char"} } # Special Titles # ============== assert theIndex.scanText(tHandle, ("#! My Project\n\n" ">> By Jane Doe <<\n\n")) assert theIndex._itemIndex[cHandle]["T000001"].references == {} assert theIndex._itemIndex[tHandle]["T000001"].level == "H1" assert theIndex._itemIndex[tHandle]["T000001"].title == "My Project" assert theIndex._itemIndex[tHandle]["T000001"].charCount == 21 assert theIndex._itemIndex[tHandle]["T000001"].wordCount == 5 assert theIndex._itemIndex[tHandle]["T000001"].paraCount == 1 assert theIndex._itemIndex[tHandle]["T000001"].synopsis == "" assert theIndex.scanText(tHandle, ("##! Prologue\n\n" "In the beginning there was time ...\n\n")) assert theIndex._itemIndex[cHandle]["T000001"].references == {} assert theIndex._itemIndex[tHandle]["T000001"].level == "H2" assert theIndex._itemIndex[tHandle]["T000001"].title == "Prologue" assert theIndex._itemIndex[tHandle]["T000001"].charCount == 43 assert theIndex._itemIndex[tHandle]["T000001"].wordCount == 8 assert theIndex._itemIndex[tHandle]["T000001"].paraCount == 1 assert theIndex._itemIndex[tHandle]["T000001"].synopsis == "" # Page wo/Title # ============= theProject.tree[pHandle]._layout = nwItemLayout.DOCUMENT assert theIndex.scanText(pHandle, ("This is a page with some text on it.\n\n")) assert theIndex._itemIndex[pHandle]["T000000"].references == {} assert theIndex._itemIndex[pHandle]["T000000"].level == "H0" assert theIndex._itemIndex[pHandle]["T000000"].title == "" assert theIndex._itemIndex[pHandle]["T000000"].charCount == 36 assert theIndex._itemIndex[pHandle]["T000000"].wordCount == 9 assert theIndex._itemIndex[pHandle]["T000000"].paraCount == 1 assert theIndex._itemIndex[pHandle]["T000000"].synopsis == "" theProject.tree[pHandle]._layout = nwItemLayout.NOTE assert theIndex.scanText(pHandle, ("This is a page with some text on it.\n\n")) assert theIndex._itemIndex[pHandle]["T000000"].references == {} assert theIndex._itemIndex[pHandle]["T000000"].level == "H0" assert theIndex._itemIndex[pHandle]["T000000"].title == "" assert theIndex._itemIndex[pHandle]["T000000"].charCount == 36 assert theIndex._itemIndex[pHandle]["T000000"].wordCount == 9 assert theIndex._itemIndex[pHandle]["T000000"].paraCount == 1 assert theIndex._itemIndex[pHandle]["T000000"].synopsis == "" assert theProject.closeProject() is True