def testCoreIndex_CheckThese(nwMinimal, dummyGUI): """Test the tag checker function checkThese. """ theProject = NWProject(dummyGUI) theProject.projTree.setSeed(42) assert theProject.openProject(nwMinimal) theIndex = NWIndex(theProject, dummyGUI) nHandle = theProject.newFile("Hello", nwItemClass.NOVEL, "a508bb932959c") cHandle = theProject.newFile("Jane", nwItemClass.CHARACTER, "afb3043c7b2b3") nItem = theProject.projTree[nHandle] cItem = theProject.projTree[cHandle] assert theIndex.scanText(cHandle, ("# Jane Smith\n" "@tag: Jane")) assert theIndex.scanText(nHandle, ("# Hello World!\n" "@pov: Jane")) assert theIndex.tagIndex == {"Jane": [2, cHandle, "CHARACTER", "T000001"]} assert theIndex.novelIndex[nHandle]["T000001"]["title"] == "Hello World!" assert theIndex.checkThese([], cItem) == [] assert theIndex.checkThese(["@tag", "Jane"], cItem) == [True, True] assert theIndex.checkThese(["@tag", "John"], cItem) == [True, True] assert theIndex.checkThese(["@tag", "Jane"], nItem) == [True, False] assert theIndex.checkThese(["@tag", "John"], nItem) == [True, True] assert theIndex.checkThese(["@pov", "John"], nItem) == [True, False] assert theIndex.checkThese(["@pov", "Jane"], nItem) == [True, True] assert theIndex.checkThese(["@ pov", "Jane"], nItem) == [False, False] assert theIndex.checkThese(["@what", "Jane"], nItem) == [False, False] assert theProject.closeProject()
def testIndexCheckThese(nwMinimal, nwDummy): """Test the tag checker function checkThese. """ theProject = NWProject(nwDummy) theProject.projTree.setSeed(42) assert theProject.openProject(nwMinimal) theIndex = NWIndex(theProject, nwDummy) nHandle = theProject.newFile("Hello", nwItemClass.NOVEL, "a508bb932959c") cHandle = theProject.newFile("Jane", nwItemClass.CHARACTER, "afb3043c7b2b3") nItem = theProject.projTree[nHandle] cItem = theProject.projTree[cHandle] assert theIndex.scanText(cHandle, ( "# Jane Smith\n" "@tag: Jane" )) assert theIndex.scanText(nHandle, ( "# Hello World!\n" "@pov: Jane" )) assert str(theIndex.tagIndex) == "{'Jane': [2, '%s', 'CHARACTER', 'T000001']}" % cHandle assert theIndex.novelIndex[nHandle]["T000001"]["title"] == "Hello World!" assert str(theIndex.checkThese(["@tag", "Jane"], cItem)) == "[True, True]" assert str(theIndex.checkThese(["@tag", "John"], cItem)) == "[True, True]" assert str(theIndex.checkThese(["@tag", "Jane"], nItem)) == "[True, False]" assert str(theIndex.checkThese(["@tag", "John"], nItem)) == "[True, True]" assert str(theIndex.checkThese(["@pov", "John"], nItem)) == "[True, False]" assert str(theIndex.checkThese(["@pov", "Jane"], nItem)) == "[True, True]" assert str(theIndex.checkThese(["@ pov", "Jane"], nItem)) == "[False, False]" assert str(theIndex.checkThese(["@what", "Jane"], nItem)) == "[False, False]" assert theProject.closeProject()
def testCoreIndex_CheckTagIndex(dummyGUI): """Test the tag index checker. """ theProject = NWProject(dummyGUI) theIndex = NWIndex(theProject, dummyGUI) # Valid Index theIndex._tagIndex = { "John": [3, "14298de4d9524", "CHARACTER", "T000001"], "Jane": [3, "bb2c23b3c42cc", "CHARACTER", "T000001"], } assert theIndex._checkTagIndex() is None # Wrong Key Type theIndex._tagIndex = { "John": [3, "14298de4d9524", "CHARACTER", "T000001"], 123456: [3, "bb2c23b3c42cc", "CHARACTER", "T000001"], } with pytest.raises(KeyError): theIndex._checkTagIndex() # Wrong Length theIndex._tagIndex = { "John": [3, "14298de4d9524", "CHARACTER", "T000001"], "Jane": [3, "bb2c23b3c42cc", "CHARACTER", "T000001", "Stuff"], } with pytest.raises(IndexError): theIndex._checkTagIndex() # Wrong Type of Entry 0 theIndex._tagIndex = { "John": [3, "14298de4d9524", "CHARACTER", "T000001"], "Jane": ["3", "bb2c23b3c42cc", "CHARACTER", "T000001"], } with pytest.raises(ValueError): theIndex._checkTagIndex() # Wrong Type of Entry 1 theIndex._tagIndex = { "John": [3, "14298de4d9524", "CHARACTER", "T000001"], "Jane": [3, 0xbb2c23b3c42cc, "CHARACTER", "T000001"], } with pytest.raises(ValueError): theIndex._checkTagIndex() # Wrong Type of Entry 2 theIndex._tagIndex = { "John": [3, "14298de4d9524", "CHARACTER", "T000001"], "Jane": [3, "bb2c23b3c42cc", "INVALID_CLASS", "T000001"], } with pytest.raises(ValueError): theIndex._checkTagIndex() # Wrong Type of Entry 3 theIndex._tagIndex = { "John": [3, "14298de4d9524", "CHARACTER", "T000001"], "Jane": [3, "bb2c23b3c42cc", "CHARACTER", "INVALID"], } with pytest.raises(ValueError): theIndex._checkTagIndex()
def testCoreIndex_CheckThese(nwMinimal, dummyGUI): """Test the tag checker function checkThese. """ theProject = NWProject(dummyGUI) theProject.projTree.setSeed(42) assert theProject.openProject(nwMinimal) theIndex = NWIndex(theProject, dummyGUI) nHandle = theProject.newFile("Hello", nwItemClass.NOVEL, "a508bb932959c") cHandle = theProject.newFile("Jane", nwItemClass.CHARACTER, "afb3043c7b2b3") nItem = theProject.projTree[nHandle] cItem = theProject.projTree[cHandle] assert not theIndex.novelChangedSince(0) assert not theIndex.notesChangedSince(0) assert not theIndex.indexChangedSince(0) assert theIndex.scanText(cHandle, ("# Jane Smith\n" "@tag: Jane\n" "@tag:\n" "@:\n")) assert theIndex.scanText( nHandle, ( "# Hello World!\n" "@pov: Jane\n" "@invalid: John\n" # Checks for issue #688 )) assert theIndex._tagIndex == {"Jane": [2, cHandle, "CHARACTER", "T000001"]} assert theIndex.getNovelData(nHandle, "T000001")["title"] == "Hello World!" assert theIndex.getReferences(nHandle, "T000001") == { "@char": [], "@custom": [], "@entity": [], "@focus": [], "@location": [], "@object": [], "@plot": [], "@pov": ["Jane"], "@time": [] } assert theIndex.novelChangedSince(0) assert theIndex.notesChangedSince(0) assert theIndex.indexChangedSince(0) assert theIndex.checkThese([], cItem) == [] assert theIndex.checkThese(["@tag", "Jane"], cItem) == [True, True] assert theIndex.checkThese(["@tag", "John"], cItem) == [True, True] assert theIndex.checkThese(["@tag", "Jane"], nItem) == [True, False] assert theIndex.checkThese(["@tag", "John"], nItem) == [True, True] assert theIndex.checkThese(["@pov", "John"], nItem) == [True, False] assert theIndex.checkThese(["@pov", "Jane"], nItem) == [True, True] assert theIndex.checkThese(["@ pov", "Jane"], nItem) == [False, False] assert theIndex.checkThese(["@what", "Jane"], nItem) == [False, False] assert theProject.closeProject()
def testCoreIndex_CheckTextCounts(dummyGUI): """Test the text counts checker. """ theProject = NWProject(dummyGUI) theIndex = NWIndex(theProject, dummyGUI) # Valid Index theIndex._textCounts = { "53b69b83cdafc": [72, 15, 2], "974e400180a99": [210, 40, 2], } assert theIndex._checkTextCounts() is None # Invalid Handle theIndex._textCounts = { "53b69b83cdafc": [72, 15, 2], "h74e400180a99": [210, 40, 2], } with pytest.raises(KeyError): theIndex._checkTextCounts() # Wrong Length theIndex._textCounts = { "53b69b83cdafc": [72, 15, 2], "974e400180a99": [210, 40, 2, 8], } with pytest.raises(IndexError): theIndex._checkTextCounts() # Type of Entry 0 theIndex._textCounts = { "53b69b83cdafc": [72, 15, 2], "974e400180a99": ["210", 40, 2], } with pytest.raises(ValueError): theIndex._checkTextCounts() # Type of Entry 1 theIndex._textCounts = { "53b69b83cdafc": [72, 15, 2], "974e400180a99": [210, "40", 2], } with pytest.raises(ValueError): theIndex._checkTextCounts() # Type of Entry 2 theIndex._textCounts = { "53b69b83cdafc": [72, 15, 2], "974e400180a99": [210, 40, "2"], } with pytest.raises(ValueError): theIndex._checkTextCounts()
def testIndexScanThis(nwMinimal, nwDummy): """Test the tag scanner function scanThis. """ theProject = NWProject(nwDummy) theProject.projTree.setSeed(42) assert theProject.openProject(nwMinimal) theIndex = NWIndex(theProject, nwDummy) isValid, theBits, thePos = theIndex.scanThis("tag: this, and this") assert not isValid isValid, theBits, thePos = theIndex.scanThis("@") assert not isValid isValid, theBits, thePos = theIndex.scanThis("@:") assert not isValid isValid, theBits, thePos = theIndex.scanThis(" @a: b") assert not isValid isValid, theBits, thePos = theIndex.scanThis("@a:") assert isValid assert str(theBits) == "['@a']" assert str(thePos) == "[0]" isValid, theBits, thePos = theIndex.scanThis("@a:b") assert isValid assert str(theBits) == "['@a', 'b']" assert str(thePos) == "[0, 3]" isValid, theBits, thePos = theIndex.scanThis("@a:b,c,d") assert isValid assert str(theBits) == "['@a', 'b', 'c', 'd']" assert str(thePos) == "[0, 3, 5, 7]" isValid, theBits, thePos = theIndex.scanThis("@a : b , c , d") assert isValid assert str(theBits) == "['@a', 'b', 'c', 'd']" assert str(thePos) == "[0, 5, 9, 13]" isValid, theBits, thePos = theIndex.scanThis("@tag: this, and this") assert isValid assert str(theBits) == "['@tag', 'this', 'and this']" assert str(thePos) == "[0, 6, 12]" assert theProject.closeProject()
def testCoreIndex_ScanThis(nwMinimal, dummyGUI): """Test the tag scanner function scanThis. """ theProject = NWProject(dummyGUI) theProject.projTree.setSeed(42) assert theProject.openProject(nwMinimal) theIndex = NWIndex(theProject, dummyGUI) isValid, theBits, thePos = theIndex.scanThis("tag: this, and this") assert not isValid isValid, theBits, thePos = theIndex.scanThis("@") assert not isValid isValid, theBits, thePos = theIndex.scanThis("@:") assert not isValid isValid, theBits, thePos = theIndex.scanThis(" @a: b") assert not isValid isValid, theBits, thePos = theIndex.scanThis("@a:") assert isValid assert theBits == ["@a"] assert thePos == [0] isValid, theBits, thePos = theIndex.scanThis("@a:b") assert isValid assert theBits == ["@a", "b"] assert thePos == [0, 3] isValid, theBits, thePos = theIndex.scanThis("@a:b,c,d") assert isValid assert theBits == ["@a", "b", "c", "d"] assert thePos == [0, 3, 5, 7] isValid, theBits, thePos = theIndex.scanThis("@a : b , c , d") assert isValid assert theBits == ["@a", "b", "c", "d"] assert thePos == [0, 5, 9, 13] isValid, theBits, thePos = theIndex.scanThis("@tag: this, and this") assert isValid assert theBits == ["@tag", "this", "and this"] assert thePos == [0, 6, 12] assert theProject.closeProject()
def testIndexExtractData(nwMinimal, nwDummy): """Check the index data extraction functions. """ theProject = NWProject(nwDummy) theProject.projTree.setSeed(42) assert theProject.openProject(nwMinimal) theIndex = NWIndex(theProject, nwDummy) nHandle = theProject.newFile("Hello", nwItemClass.NOVEL, "a508bb932959c") cHandle = theProject.newFile("Jane", nwItemClass.CHARACTER, "afb3043c7b2b3") 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" )) # The novel structure should contain the pointer to the novel file header assert str(theIndex.getNovelStructure()) == "['%s:T000001']" % nHandle # The novel file should have the correct counts cC, wC, pC = theIndex.getCounts(nHandle) assert cC == 62 # Characters in text and title only assert wC == 12 # Words in text and title only assert pC == 2 # Paragraphs in text only ## # getReferences ## # Look up an ivalid handle theRefs = theIndex.getReferences("Not a handle") assert theRefs["@pov"] == [] assert theRefs["@char"] == [] # The novel file should now refer to Jane as @pov and @char theRefs = theIndex.getReferences(nHandle) assert str(theRefs["@pov"]) == "['Jane']" assert str(theRefs["@char"]) == "['Jane']" ## # getBackReferenceList ## # None handle should return an empty dict assert theIndex.getBackReferenceList(None) == {} # The character file should have a record of the reference from the novel file theRefs = theIndex.getBackReferenceList(cHandle) assert str(theRefs) == "{'%s': 'T000001'}" % nHandle ## # getTagSource ## assert theIndex.getTagSource("Jane") == (cHandle, 2, "T000001") assert theIndex.getTagSource("John") == (None, 0, "T000000") ## # getCounts for whole text and sections ## # Get section counts for a novel file 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\n" "# 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" )) # Whole document cC, wC, pC = theIndex.getCounts(nHandle) assert cC == 124 assert wC == 24 assert pC == 4 # First part cC, wC, pC = theIndex.getCounts(nHandle, "T000001") assert cC == 62 assert wC == 12 assert pC == 2 # First part cC, wC, pC = theIndex.getCounts(nHandle, "T000011") assert cC == 62 assert wC == 12 assert pC == 2 # Get section counts for a note file assert theIndex.scanText(cHandle, ( "# 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\n" "# 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" )) # Whole document cC, wC, pC = theIndex.getCounts(cHandle) assert cC == 124 assert wC == 24 assert pC == 4 # First part cC, wC, pC = theIndex.getCounts(cHandle, "T000001") assert cC == 62 assert wC == 12 assert pC == 2 # First part cC, wC, pC = theIndex.getCounts(cHandle, "T000011") assert cC == 62 assert wC == 12 assert pC == 2 assert theProject.closeProject()
def testIndexScanText(nwMinimal, nwDummy): """Check the index data extraction functions. """ theProject = NWProject(nwDummy) theProject.projTree.setSeed(42) assert theProject.openProject(nwMinimal) theIndex = NWIndex(theProject, nwDummy) # 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 not theIndex.scanText(None, "Hello World!") assert not theIndex.scanText(dHandle, "Hello World!") assert not theIndex.scanText(xHandle, "Hello World!") xItem.setLayout(nwItemLayout.SCENE) xItem.setParent(None) assert not theIndex.scanText(xHandle, "Hello World!") # Create the trash folder tHandle = theProject.trashFolder() assert theProject.projTree[tHandle] is not None xItem.setParent(tHandle) assert not theIndex.scanText(xHandle, "Hello World!") # Create the archive root aHandle = theProject.newRoot("Outtakes", nwItemClass.ARCHIVE) assert theProject.projTree[aHandle] is not None xItem.setParent(aHandle) assert not theIndex.scanText(xHandle, "Hello World!") # Make some usable items nHandle = theProject.newFile("Hello", nwItemClass.NOVEL, "a508bb932959c") cHandle = theProject.newFile("Jane", nwItemClass.CHARACTER, "afb3043c7b2b3") sHandle = theProject.newFile("Scene", nwItemClass.NOVEL, "a508bb932959c") # 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 str(theIndex.tagIndex) == "{'Jane': [2, '%s', 'CHARACTER', 'T000001']}" % cHandle assert theIndex.novelIndex[nHandle]["T000001"]["title"] == "Hello World!" # Check that title sections are indexed properly 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 is counted as a word "Paragraph Five.\n\n" )) assert theIndex.refIndex[nHandle].get("T000000", None) is not None # Always there assert theIndex.refIndex[nHandle].get("T000001", None) is not None # Heading 1 assert theIndex.refIndex[nHandle].get("T000002", None) is None assert theIndex.refIndex[nHandle].get("T000003", None) is None assert theIndex.refIndex[nHandle].get("T000004", None) is None assert theIndex.refIndex[nHandle].get("T000005", None) is None assert theIndex.refIndex[nHandle].get("T000006", None) is None assert theIndex.refIndex[nHandle].get("T000007", None) is not None # Heading 2 assert theIndex.refIndex[nHandle].get("T000008", None) is None assert theIndex.refIndex[nHandle].get("T000009", None) is None assert theIndex.refIndex[nHandle].get("T000010", None) is None assert theIndex.refIndex[nHandle].get("T000011", None) is None assert theIndex.refIndex[nHandle].get("T000012", None) is None assert theIndex.refIndex[nHandle].get("T000013", None) is not None # Heading 3 assert theIndex.refIndex[nHandle].get("T000014", None) is None assert theIndex.refIndex[nHandle].get("T000015", None) is None assert theIndex.refIndex[nHandle].get("T000016", None) is None assert theIndex.refIndex[nHandle].get("T000017", None) is None assert theIndex.refIndex[nHandle].get("T000018", None) is None assert theIndex.refIndex[nHandle].get("T000019", None) is not None # Heading 4 assert theIndex.refIndex[nHandle].get("T000020", None) is None assert theIndex.refIndex[nHandle].get("T000021", None) is None assert theIndex.refIndex[nHandle].get("T000022", None) is None assert theIndex.refIndex[nHandle].get("T000023", None) is None assert theIndex.refIndex[nHandle].get("T000024", None) is None assert theIndex.refIndex[nHandle].get("T000025", None) is None assert theIndex.refIndex[nHandle].get("T000026", None) is None assert theIndex.novelIndex[nHandle]["T000001"]["level"] == "H1" assert theIndex.novelIndex[nHandle]["T000007"]["level"] == "H2" assert theIndex.novelIndex[nHandle]["T000013"]["level"] == "H3" assert theIndex.novelIndex[nHandle]["T000019"]["level"] == "H4" assert theIndex.novelIndex[nHandle]["T000001"]["title"] == "Title One" assert theIndex.novelIndex[nHandle]["T000007"]["title"] == "Title Two" assert theIndex.novelIndex[nHandle]["T000013"]["title"] == "Title Three" assert theIndex.novelIndex[nHandle]["T000019"]["title"] == "Title Four" assert theIndex.novelIndex[nHandle]["T000001"]["layout"] == "SCENE" assert theIndex.novelIndex[nHandle]["T000007"]["layout"] == "SCENE" assert theIndex.novelIndex[nHandle]["T000013"]["layout"] == "SCENE" assert theIndex.novelIndex[nHandle]["T000019"]["layout"] == "SCENE" assert theIndex.novelIndex[nHandle]["T000001"]["synopsis"] == "Synopsis One." assert theIndex.novelIndex[nHandle]["T000007"]["synopsis"] == "Synopsis Two." assert theIndex.novelIndex[nHandle]["T000013"]["synopsis"] == "Synopsis Three." assert theIndex.novelIndex[nHandle]["T000019"]["synopsis"] == "Synopsis Four." assert theIndex.novelIndex[nHandle]["T000001"]["cCount"] == 23 assert theIndex.novelIndex[nHandle]["T000007"]["cCount"] == 23 assert theIndex.novelIndex[nHandle]["T000013"]["cCount"] == 27 assert theIndex.novelIndex[nHandle]["T000019"]["cCount"] == 56 assert theIndex.novelIndex[nHandle]["T000001"]["wCount"] == 4 assert theIndex.novelIndex[nHandle]["T000007"]["wCount"] == 4 assert theIndex.novelIndex[nHandle]["T000013"]["wCount"] == 4 assert theIndex.novelIndex[nHandle]["T000019"]["wCount"] == 9 assert theIndex.novelIndex[nHandle]["T000001"]["pCount"] == 1 assert theIndex.novelIndex[nHandle]["T000007"]["pCount"] == 1 assert theIndex.novelIndex[nHandle]["T000013"]["pCount"] == 1 assert theIndex.novelIndex[nHandle]["T000019"]["pCount"] == 3 assert theIndex.scanText(cHandle, ( "# Title One\n\n" "@tag: One\n\n" "% synopsis: Synopsis One.\n\n" "Paragraph One.\n\n" )) assert theIndex.refIndex[cHandle].get("T000000", None) is not None assert theIndex.refIndex[cHandle].get("T000001", None) is not None assert theIndex.refIndex[cHandle].get("T000002", None) is None assert theIndex.refIndex[cHandle].get("T000003", None) is None assert theIndex.refIndex[cHandle].get("T000004", None) is None assert theIndex.refIndex[cHandle].get("T000005", None) is None assert theIndex.refIndex[cHandle].get("T000006", None) is None assert theIndex.refIndex[cHandle].get("T000007", None) is None assert theIndex.noteIndex[cHandle]["T000001"]["level"] == "H1" assert theIndex.noteIndex[cHandle]["T000001"]["title"] == "Title One" assert theIndex.noteIndex[cHandle]["T000001"]["layout"] == "NOTE" assert theIndex.noteIndex[cHandle]["T000001"]["synopsis"] == "Synopsis One." assert theIndex.noteIndex[cHandle]["T000001"]["cCount"] == 23 assert theIndex.noteIndex[cHandle]["T000001"]["wCount"] == 4 assert theIndex.noteIndex[cHandle]["T000001"]["pCount"] == 1 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 str(theIndex.refIndex[sHandle]["T000001"]["tags"]) == ( "[[3, '@pov', 'One'], [5, '@char', 'Two']]" ) assert theProject.closeProject()
def testIndexBuildCheck(monkeypatch, nwLipsum, nwDummy, nwTempProj, nwRef): """Test core functionality of scaning, saving, loading and checking the index cache file. """ projFile = os.path.join(nwLipsum, "meta", "tagsIndex.json") testFile = os.path.join(nwTempProj, "1_tagsIndex.json") refFile = os.path.join(nwRef, "proj", "1_tagsIndex.json") theProject = NWProject(nwDummy) theProject.projTree.setSeed(42) assert theProject.openProject(nwLipsum) monkeypatch.setattr("nw.core.index.time", lambda: 123.4) theIndex = NWIndex(theProject, nwDummy) notIndexable = { "b3643d0f92e32": False, # Novel ROOT "45e6b01ca35c1": False, # Chapter One FOLDER "6bd935d2490cd": False, # Chapter Two FOLDER "67a8707f2f249": False, # Character ROOT "6c6afb1247750": False, # Plot ROOT "60bdf227455cc": False, # World ROOT } for tItem in theProject.projTree: assert theIndex.reIndexHandle(tItem.itemHandle) is notIndexable.get(tItem.itemHandle, True) assert not theIndex.reIndexHandle(None) # Dummy exception function def doPanic(*arg, **kwargs): raise Exception # Make the save fail monkeypatch.setattr(json, "dump", doPanic) assert not theIndex.saveIndex() # Make the save pass monkeypatch.undo() assert theIndex.saveIndex() # Take a copy of the index tagIndex = str(theIndex.tagIndex) refIndex = str(theIndex.refIndex) novelIndex = str(theIndex.novelIndex) noteIndex = str(theIndex.noteIndex) textCounts = str(theIndex.textCounts) # Delete a handle assert theIndex.tagIndex.get("Bod", None) is not None assert theIndex.refIndex.get("4c4f28287af27", None) is not None assert theIndex.noteIndex.get("4c4f28287af27", None) is not None assert theIndex.textCounts.get("4c4f28287af27", None) is not None theIndex.deleteHandle("4c4f28287af27") assert theIndex.tagIndex.get("Bod", None) is None assert theIndex.refIndex.get("4c4f28287af27", None) is None assert theIndex.noteIndex.get("4c4f28287af27", None) is None assert theIndex.textCounts.get("4c4f28287af27", None) is None # Clear the index theIndex.clearIndex() assert not theIndex.tagIndex assert not theIndex.refIndex assert not theIndex.novelIndex assert not theIndex.noteIndex assert not theIndex.textCounts # Make the load fail monkeypatch.setattr(json, "load", doPanic) assert not theIndex.loadIndex() # Make the load pass monkeypatch.undo() assert theIndex.loadIndex() assert str(theIndex.tagIndex) == tagIndex assert str(theIndex.refIndex) == refIndex assert str(theIndex.novelIndex) == novelIndex assert str(theIndex.noteIndex) == noteIndex assert str(theIndex.textCounts) == textCounts # Break the index and check that we notice assert not theIndex.indexBroken theIndex.tagIndex["Bod"].append("Stuff") # No longer len() == 4 theIndex.checkIndex() assert theIndex.indexBroken assert theIndex.loadIndex() assert not theIndex.indexBroken theIndex.refIndex["fb609cd8319dc"]["T000001"]["tags"].append("Stuff") # No longer len() == 3 theIndex.checkIndex() assert theIndex.indexBroken assert theIndex.loadIndex() assert not theIndex.indexBroken theIndex.novelIndex["7a992350f3eb6"]["T000001"]["Stuff"] = "" # No longer len(keys()) == 8 theIndex.checkIndex() assert theIndex.indexBroken assert theIndex.loadIndex() assert not theIndex.indexBroken theIndex.noteIndex["4c4f28287af27"]["T000001"]["Stuff"] = "" # No longer len(keys()) == 8 theIndex.checkIndex() assert theIndex.indexBroken assert theIndex.loadIndex() assert not theIndex.indexBroken theIndex.textCounts["7a992350f3eb6"].append("Stuff") # No longer len() == 3 theIndex.checkIndex() assert theIndex.indexBroken # Make the try/except trigger as well assert theIndex.loadIndex() assert not theIndex.indexBroken theIndex.refIndex["fb609cd8319dc"]["T000001"] = {"tagssss": []} # Wrong key name theIndex.checkIndex() assert theIndex.indexBroken # Finalise assert theProject.closeProject() copyfile(projFile, testFile) assert cmpFiles(testFile, refFile)
def testCoreIndex_CheckNovelNoteIndex(dummyGUI): """Test the novel and note index checkers. """ theProject = NWProject(dummyGUI) theIndex = NWIndex(theProject, dummyGUI) # Valid Index theIndex._novelIndex = { "53b69b83cdafc": { "T000001": { "level": "H1", "title": "My Novel", "layout": "TITLE", "synopsis": "text", "cCount": 72, "wCount": 15, "pCount": 2, "updated": 1611922868 } } } theIndex._noteIndex = theIndex._novelIndex.copy() assert theIndex._checkNovelNoteIndex("novelIndex") is None assert theIndex._checkNovelNoteIndex("noteIndex") is None with pytest.raises(IndexError): theIndex._checkNovelNoteIndex("notAnIndex") # Invalid Handle theIndex._novelIndex = { "H3b69b83cdafc": { "T000001": { "level": "H1", "title": "My Novel", "layout": "TITLE", "synopsis": "text", "cCount": 72, "wCount": 15, "pCount": 2, "updated": 1611922868 } } } with pytest.raises(KeyError): theIndex._checkNovelNoteIndex("novelIndex") # Invalid Title theIndex._novelIndex = { "53b69b83cdafc": { "INVALID": { "level": "H1", "title": "My Novel", "layout": "TITLE", "synopsis": "text", "cCount": 72, "wCount": 15, "pCount": 2, "updated": 1611922868 } } } with pytest.raises(KeyError): theIndex._checkNovelNoteIndex("novelIndex") # Wrong Length theIndex._novelIndex = { "53b69b83cdafc": { "T000001": { "level": "H1", "title": "My Novel", "layout": "TITLE", "synopsis": "text", "cCount": 72, "wCount": 15, "pCount": 2, "updated": 1611922868, "stuff": None } } } with pytest.raises(IndexError): theIndex._checkNovelNoteIndex("novelIndex") # Missing Keys # ============ # Missing 'level' theIndex._novelIndex = { "53b69b83cdafc": { "T000001": { "stuff": "H1", "title": "My Novel", "layout": "TITLE", "synopsis": "text", "cCount": 72, "wCount": 15, "pCount": 2, "updated": 1611922868 } } } with pytest.raises(KeyError): theIndex._checkNovelNoteIndex("novelIndex") # Missing 'title' theIndex._novelIndex = { "53b69b83cdafc": { "T000001": { "level": "H1", "stuff": "My Novel", "layout": "TITLE", "synopsis": "text", "cCount": 72, "wCount": 15, "pCount": 2, "updated": 1611922868 } } } with pytest.raises(KeyError): theIndex._checkNovelNoteIndex("novelIndex") # Missing 'layout' theIndex._novelIndex = { "53b69b83cdafc": { "T000001": { "level": "H1", "title": "My Novel", "stuff": "TITLE", "synopsis": "text", "cCount": 72, "wCount": 15, "pCount": 2, "updated": 1611922868 } } } with pytest.raises(KeyError): theIndex._checkNovelNoteIndex("novelIndex") # Missing 'synopsis' theIndex._novelIndex = { "53b69b83cdafc": { "T000001": { "level": "H1", "title": "My Novel", "layout": "TITLE", "stuff": "text", "cCount": 72, "wCount": 15, "pCount": 2, "updated": 1611922868 } } } with pytest.raises(KeyError): theIndex._checkNovelNoteIndex("novelIndex") # Missing 'cCount' theIndex._novelIndex = { "53b69b83cdafc": { "T000001": { "level": "H1", "title": "My Novel", "layout": "TITLE", "synopsis": "text", "stuff": 72, "wCount": 15, "pCount": 2, "updated": 1611922868 } } } with pytest.raises(KeyError): theIndex._checkNovelNoteIndex("novelIndex") # Missing 'wCount' theIndex._novelIndex = { "53b69b83cdafc": { "T000001": { "level": "H1", "title": "My Novel", "layout": "TITLE", "synopsis": "text", "cCount": 72, "stuff": 15, "pCount": 2, "updated": 1611922868 } } } with pytest.raises(KeyError): theIndex._checkNovelNoteIndex("novelIndex") # Missing 'pCount' theIndex._novelIndex = { "53b69b83cdafc": { "T000001": { "level": "H1", "title": "My Novel", "layout": "TITLE", "synopsis": "text", "cCount": 72, "wCount": 15, "stuff": 2, "updated": 1611922868 } } } with pytest.raises(KeyError): theIndex._checkNovelNoteIndex("novelIndex") # Missing 'updated' theIndex._novelIndex = { "53b69b83cdafc": { "T000001": { "level": "H1", "title": "My Novel", "layout": "TITLE", "synopsis": "text", "cCount": 72, "wCount": 15, "pCount": 2, "stuff": 1611922868 } } } with pytest.raises(KeyError): theIndex._checkNovelNoteIndex("novelIndex") # Wrong Types # =========== # Wrong Type for 'level' theIndex._novelIndex = { "53b69b83cdafc": { "T000001": { "level": "XX", "title": "My Novel", "layout": "TITLE", "synopsis": "text", "cCount": 72, "wCount": 15, "pCount": 2, "updated": 1611922868 } } } with pytest.raises(ValueError): theIndex._checkNovelNoteIndex("novelIndex") # Wrong Type for 'title' theIndex._novelIndex = { "53b69b83cdafc": { "T000001": { "level": "H1", "title": 12345678, "layout": "TITLE", "synopsis": "text", "cCount": 72, "wCount": 15, "pCount": 2, "updated": 1611922868 } } } with pytest.raises(ValueError): theIndex._checkNovelNoteIndex("novelIndex") # Wrong Type for 'layout' theIndex._novelIndex = { "53b69b83cdafc": { "T000001": { "level": "H1", "title": "My Novel", "layout": "INVALID", "synopsis": "text", "cCount": 72, "wCount": 15, "pCount": 2, "updated": 1611922868 } } } with pytest.raises(ValueError): theIndex._checkNovelNoteIndex("novelIndex") # Wrong Type for 'synopsis' theIndex._novelIndex = { "53b69b83cdafc": { "T000001": { "level": "H1", "title": "My Novel", "layout": "TITLE", "synopsis": 123456, "cCount": 72, "wCount": 15, "pCount": 2, "updated": 1611922868 } } } with pytest.raises(ValueError): theIndex._checkNovelNoteIndex("novelIndex") # Wrong Type for 'cCount' theIndex._novelIndex = { "53b69b83cdafc": { "T000001": { "level": "H1", "title": "My Novel", "layout": "TITLE", "synopsis": "text", "cCount": "72", "wCount": 15, "pCount": 2, "updated": 1611922868 } } } with pytest.raises(ValueError): theIndex._checkNovelNoteIndex("novelIndex") # Wrong Type for 'wCount' theIndex._novelIndex = { "53b69b83cdafc": { "T000001": { "level": "H1", "title": "My Novel", "layout": "TITLE", "synopsis": "text", "cCount": 72, "wCount": "15", "pCount": 2, "updated": 1611922868 } } } with pytest.raises(ValueError): theIndex._checkNovelNoteIndex("novelIndex") # Wrong Type for 'pCount' theIndex._novelIndex = { "53b69b83cdafc": { "T000001": { "level": "H1", "title": "My Novel", "layout": "TITLE", "synopsis": "text", "cCount": 72, "wCount": 15, "pCount": "2", "updated": 1611922868 } } } with pytest.raises(ValueError): theIndex._checkNovelNoteIndex("novelIndex") # Wrong Type for 'updated' theIndex._novelIndex = { "53b69b83cdafc": { "T000001": { "level": "H1", "title": "My Novel", "layout": "TITLE", "synopsis": "text", "cCount": 72, "wCount": 15, "pCount": 2, "updated": "1611922868" } } } with pytest.raises(ValueError): theIndex._checkNovelNoteIndex("novelIndex")
def testCoreIndex_CheckRefIndex(dummyGUI): """Test the reference index checker. """ theProject = NWProject(dummyGUI) theIndex = NWIndex(theProject, dummyGUI) # Valid Index theIndex._refIndex = { "6a2d6d5f4f401": { "T000000": { "tags": [], "updated": 1611922868 }, "T000001": { "tags": [[3, "@pov", "Jane"], [4, "@location", "Earth"]], "updated": 1611922868 } } } assert theIndex._checkRefIndex() is None # Invalid Handle theIndex._refIndex = { "Ha2d6d5f4f401": { "T000000": { "tags": [], "updated": 1611922868 }, "T000001": { "tags": [[3, "@pov", "Jane"], [4, "@location", "Earth"]], "updated": 1611922868 } } } with pytest.raises(KeyError): theIndex._checkRefIndex() # Invalid Title theIndex._refIndex = { "6a2d6d5f4f401": { "T000000": { "tags": [], "updated": 1611922868 }, "INVALID": { "tags": [[3, "@pov", "Jane"], [4, "@location", "Earth"]], "updated": 1611922868 } } } with pytest.raises(KeyError): theIndex._checkRefIndex() # Missing 'tags' theIndex._refIndex = { "6a2d6d5f4f401": { "T000000": { "tags": [], "updated": 1611922868 }, "T000001": { "updated": 1611922868 } } } with pytest.raises(KeyError): theIndex._checkRefIndex() # Wrong Length of 'tags' theIndex._refIndex = { "6a2d6d5f4f401": { "T000000": { "tags": [], "updated": 1611922868 }, "T000001": { "tags": [[3, "@pov", "Jane"], [4, "@location", "Earth", "Stuff"]], "updated": 1611922868 } } } with pytest.raises(IndexError): theIndex._checkRefIndex() # Wrong Type of 'tags' Entry 0 theIndex._refIndex = { "6a2d6d5f4f401": { "T000000": { "tags": [], "updated": 1611922868 }, "T000001": { "tags": [[3, "@pov", "Jane"], ["4", "@location", "Earth"]], "updated": 1611922868 } } } with pytest.raises(ValueError): theIndex._checkRefIndex() # Wrong Type of 'tags' Entry 1 theIndex._refIndex = { "6a2d6d5f4f401": { "T000000": { "tags": [], "updated": 1611922868 }, "T000001": { "tags": [[3, "@pov", "Jane"], [4, "@stuff", "Earth"]], "updated": 1611922868 } } } with pytest.raises(ValueError): theIndex._checkRefIndex() # Wrong Type of 'tags' Entry 1 theIndex._refIndex = { "6a2d6d5f4f401": { "T000000": { "tags": [], "updated": 1611922868 }, "T000001": { "tags": [[3, "@pov", "Jane"], [4, "@location", 123456]], "updated": 1611922868 } } } with pytest.raises(ValueError): theIndex._checkRefIndex() # Missing 'updated' theIndex._refIndex = { "6a2d6d5f4f401": { "T000000": { "tags": [], "updated": 1611922868 }, "T000001": { "tags": [] } } } with pytest.raises(KeyError): theIndex._checkRefIndex() # Wrong Type of 'updated' Entry 1 theIndex._refIndex = { "6a2d6d5f4f401": { "T000000": { "tags": [], "updated": 1611922868 }, "T000001": { "tags": [], "updated": "1611922868" } } } with pytest.raises(ValueError): theIndex._checkRefIndex()
def testCoreIndex_ExtractData(nwMinimal, dummyGUI): """Check the index data extraction functions. """ theProject = NWProject(dummyGUI) theProject.projTree.setSeed(42) assert theProject.openProject(nwMinimal) theIndex = NWIndex(theProject, dummyGUI) nHandle = theProject.newFile("Hello", nwItemClass.NOVEL, "a508bb932959c") cHandle = theProject.newFile("Jane", nwItemClass.CHARACTER, "afb3043c7b2b3") assert theIndex.getNovelData("", "") is None assert theIndex.getNovelData("a508bb932959c", "") is None 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")) # The novel structure should contain the pointer to the novel file header theKeys = [] for aKey, _, _, _ in theIndex.novelStructure(): theKeys.append(aKey) assert theKeys == ["%s:T000001" % nHandle] # Check that excluded files can be skipped theProject.projTree[nHandle].setExported(False) theKeys = [] for aKey, _, _, _ in theIndex.novelStructure(skipExcluded=False): theKeys.append(aKey) assert theKeys == ["%s:T000001" % nHandle] theKeys = [] for aKey, _, _, _ in theIndex.novelStructure(skipExcluded=True): theKeys.append(aKey) assert theKeys == [] theKeys = [] for aKey, _, _, _ in theIndex.novelStructure(): theKeys.append(aKey) assert theKeys == [] # The novel file should have the correct counts cC, wC, pC = theIndex.getCounts(nHandle) assert cC == 62 # Characters in text and title only assert wC == 12 # Words in text and title only assert pC == 2 # Paragraphs in text only # getReferences # ============= # Look up an ivalid handle theRefs = theIndex.getReferences("Not a handle") assert theRefs["@pov"] == [] assert theRefs["@char"] == [] # The novel file should now refer to Jane as @pov and @char theRefs = theIndex.getReferences(nHandle) assert theRefs["@pov"] == ["Jane"] assert theRefs["@char"] == ["Jane"] # getBackReferenceList # ==================== # None handle should return an empty dict assert theIndex.getBackReferenceList(None) == {} # The character file should have a record of the reference from the novel file theRefs = theIndex.getBackReferenceList(cHandle) assert theRefs == {nHandle: "T000001"} # getTagSource # ============ assert theIndex.getTagSource("Jane") == (cHandle, 2, "T000001") assert theIndex.getTagSource("John") == (None, 0, "T000000") # getCounts # ========= # For whole text and sections # Get section counts for a novel file 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\n" "# 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. She's still awesome though.\n")) # Whole document cC, wC, pC = theIndex.getCounts(nHandle) assert cC == 152 assert wC == 28 assert pC == 4 # First part cC, wC, pC = theIndex.getCounts(nHandle, "T000001") assert cC == 62 assert wC == 12 assert pC == 2 # Second part cC, wC, pC = theIndex.getCounts(nHandle, "T000011") assert cC == 90 assert wC == 16 assert pC == 2 # Get section counts for a note file assert theIndex.scanText( cHandle, ("# 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\n" "# 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. She's still awesome though.\n")) # Whole document cC, wC, pC = theIndex.getCounts(cHandle) assert cC == 152 assert wC == 28 assert pC == 4 # First part cC, wC, pC = theIndex.getCounts(cHandle, "T000001") assert cC == 62 assert wC == 12 assert pC == 2 # Second part cC, wC, pC = theIndex.getCounts(cHandle, "T000011") assert cC == 90 assert wC == 16 assert pC == 2 # Novel Stats # =========== hHandle = theProject.newFile("Chapter", nwItemClass.NOVEL, "a508bb932959c") sHandle = theProject.newFile("Scene One", nwItemClass.NOVEL, "a508bb932959c") tHandle = theProject.newFile("Scene Two", nwItemClass.NOVEL, "a508bb932959c") theProject.projTree[hHandle].itemLayout == nwItemLayout.CHAPTER theProject.projTree[sHandle].itemLayout == nwItemLayout.SCENE theProject.projTree[tHandle].itemLayout == nwItemLayout.SCENE assert theIndex.scanText(hHandle, "## Chapter One\n\n") assert theIndex.scanText(sHandle, "### Scene One\n\n") assert theIndex.scanText(tHandle, "### Scene Two\n\n") assert theIndex._listNovelHandles(False) == [ nHandle, hHandle, sHandle, tHandle ] assert theIndex._listNovelHandles(True) == [hHandle, sHandle, tHandle] # Add a fake handle to the tree and check that it's ignored theProject.projTree._treeOrder.append("0000000000000") assert theIndex._listNovelHandles(False) == [ nHandle, hHandle, sHandle, tHandle ] theProject.projTree._treeOrder.remove("0000000000000") # Extract stats assert theIndex.getNovelWordCount(False) == 34 assert theIndex.getNovelWordCount(True) == 6 assert theIndex.getNovelTitleCounts(False) == [0, 2, 1, 2, 0] assert theIndex.getNovelTitleCounts(True) == [0, 0, 1, 2, 0] # Table of Contents assert theIndex.getTableOfContents(0, True) == [] assert theIndex.getTableOfContents(1, True) == [] assert theIndex.getTableOfContents(2, True) == [ ("%s:T000001" % hHandle, 2, "Chapter One", 6), ] assert theIndex.getTableOfContents(3, True) == [ ("%s:T000001" % hHandle, 2, "Chapter One", 2), ("%s:T000001" % sHandle, 3, "Scene One", 2), ("%s:T000001" % tHandle, 3, "Scene Two", 2), ] assert theIndex.getTableOfContents(0, False) == [] assert theIndex.getTableOfContents(1, False) == [ ("%s:T000001" % nHandle, 1, "Hello World!", 12), ("%s:T000011" % nHandle, 1, "Hello World!", 22), ] # Header Word Counts bHandle = "0000000000000" assert theIndex.getHandleWordCounts(bHandle) == [] assert theIndex.getHandleWordCounts(hHandle) == [("%s:T000001" % hHandle, 2)] assert theIndex.getHandleWordCounts(sHandle) == [("%s:T000001" % sHandle, 2)] assert theIndex.getHandleWordCounts(tHandle) == [("%s:T000001" % tHandle, 2)] assert theIndex.getHandleWordCounts(nHandle) == [ ("%s:T000001" % nHandle, 12), ("%s:T000011" % nHandle, 16) ] assert theProject.closeProject() # Header Record bHandle = "0000000000000" assert theIndex.getHandleHeaders(bHandle) == [] assert theIndex.getHandleHeaders(hHandle) == [("T000001", "H2", "Chapter One")] assert theIndex.getHandleHeaders(sHandle) == [("T000001", "H3", "Scene One")] assert theIndex.getHandleHeaders(tHandle) == [("T000001", "H3", "Scene Two")] assert theIndex.getHandleHeaders(nHandle) == [ ("T000001", "H1", "Hello World!"), ("T000011", "H1", "Hello World!") ]
def testCoreIndex_LoadSave(monkeypatch, nwLipsum, dummyGUI, outDir, refDir): """Test core functionality of scaning, saving, loading and checking the index cache file. """ projFile = os.path.join(nwLipsum, "meta", "tagsIndex.json") testFile = os.path.join(outDir, "coreIndex_LoadSave_tagsIndex.json") compFile = os.path.join(refDir, "coreIndex_LoadSave_tagsIndex.json") theProject = NWProject(dummyGUI) theProject.projTree.setSeed(42) assert theProject.openProject(nwLipsum) monkeypatch.setattr("nw.core.index.time", lambda: 123.4) theIndex = NWIndex(theProject, dummyGUI) notIndexable = { "b3643d0f92e32": False, # Novel ROOT "45e6b01ca35c1": False, # Chapter One FOLDER "6bd935d2490cd": False, # Chapter Two FOLDER "67a8707f2f249": False, # Character ROOT "6c6afb1247750": False, # Plot ROOT "60bdf227455cc": False, # World ROOT } for tItem in theProject.projTree: assert theIndex.reIndexHandle(tItem.itemHandle) is notIndexable.get( tItem.itemHandle, True) assert not theIndex.reIndexHandle(None) # Make the save fail with monkeypatch.context() as mp: mp.setattr(json, "dump", causeException) assert not theIndex.saveIndex() # Make the save pass assert theIndex.saveIndex() # Take a copy of the index tagIndex = str(theIndex._tagIndex) refIndex = str(theIndex._refIndex) novelIndex = str(theIndex._novelIndex) noteIndex = str(theIndex._noteIndex) textCounts = str(theIndex._textCounts) # Delete a handle assert theIndex._tagIndex.get("Bod", None) is not None assert theIndex._refIndex.get("4c4f28287af27", None) is not None assert theIndex._noteIndex.get("4c4f28287af27", None) is not None assert theIndex._textCounts.get("4c4f28287af27", None) is not None theIndex.deleteHandle("4c4f28287af27") assert theIndex._tagIndex.get("Bod", None) is None assert theIndex._refIndex.get("4c4f28287af27", None) is None assert theIndex._noteIndex.get("4c4f28287af27", None) is None assert theIndex._textCounts.get("4c4f28287af27", None) is None # Clear the index theIndex.clearIndex() assert not theIndex._tagIndex assert not theIndex._refIndex assert not theIndex._novelIndex assert not theIndex._noteIndex assert not theIndex._textCounts # Make the load fail with monkeypatch.context() as mp: mp.setattr(json, "load", causeException) assert not theIndex.loadIndex() # Make the load pass assert theIndex.loadIndex() assert str(theIndex._tagIndex) == tagIndex assert str(theIndex._refIndex) == refIndex assert str(theIndex._novelIndex) == novelIndex assert str(theIndex._noteIndex) == noteIndex assert str(theIndex._textCounts) == textCounts # Break the index and check that we notice assert not theIndex.indexBroken theIndex._tagIndex["Bod"].append("Stuff") theIndex.checkIndex() assert theIndex.indexBroken # Finalise assert theProject.closeProject() copyfile(projFile, testFile) assert cmpFiles(testFile, compFile)
def testCoreIndex_ScanText(nwMinimal, dummyGUI): """Check the index text scanner. """ theProject = NWProject(dummyGUI) theProject.projTree.setSeed(42) assert theProject.openProject(nwMinimal) theIndex = NWIndex(theProject, dummyGUI) # 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 not theIndex.scanText(None, "Hello World!") assert not theIndex.scanText(dHandle, "Hello World!") assert not theIndex.scanText(xHandle, "Hello World!") xItem.setLayout(nwItemLayout.SCENE) xItem.setParent(None) assert not theIndex.scanText(xHandle, "Hello World!") # Create the trash folder tHandle = theProject.trashFolder() assert theProject.projTree[tHandle] is not None xItem.setParent(tHandle) assert not theIndex.scanText(xHandle, "Hello World!") # Create the archive root aHandle = theProject.newRoot("Outtakes", nwItemClass.ARCHIVE) assert theProject.projTree[aHandle] is not None xItem.setParent(aHandle) assert not theIndex.scanText(xHandle, "Hello World!") # Make some usable items 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") # 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!" # Check that title sections are indexed properly 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._refIndex[nHandle].get("T000000", None) is not None # Always there assert theIndex._refIndex[nHandle].get("T000001", None) is not None # Heading 1 assert theIndex._refIndex[nHandle].get("T000002", None) is None assert theIndex._refIndex[nHandle].get("T000003", None) is None assert theIndex._refIndex[nHandle].get("T000004", None) is None assert theIndex._refIndex[nHandle].get("T000005", None) is None assert theIndex._refIndex[nHandle].get("T000006", None) is None assert theIndex._refIndex[nHandle].get("T000007", None) is not None # Heading 2 assert theIndex._refIndex[nHandle].get("T000008", None) is None assert theIndex._refIndex[nHandle].get("T000009", None) is None assert theIndex._refIndex[nHandle].get("T000010", None) is None assert theIndex._refIndex[nHandle].get("T000011", None) is None assert theIndex._refIndex[nHandle].get("T000012", None) is None assert theIndex._refIndex[nHandle].get("T000013", None) is not None # Heading 3 assert theIndex._refIndex[nHandle].get("T000014", None) is None assert theIndex._refIndex[nHandle].get("T000015", None) is None assert theIndex._refIndex[nHandle].get("T000016", None) is None assert theIndex._refIndex[nHandle].get("T000017", None) is None assert theIndex._refIndex[nHandle].get("T000018", None) is None assert theIndex._refIndex[nHandle].get("T000019", None) is not None # Heading 4 assert theIndex._refIndex[nHandle].get("T000020", None) is None assert theIndex._refIndex[nHandle].get("T000021", None) is None assert theIndex._refIndex[nHandle].get("T000022", None) is None assert theIndex._refIndex[nHandle].get("T000023", None) is None assert theIndex._refIndex[nHandle].get("T000024", None) is None assert theIndex._refIndex[nHandle].get("T000025", None) is None assert theIndex._refIndex[nHandle].get("T000026", None) is None assert theIndex._novelIndex[nHandle]["T000001"]["level"] == "H1" assert theIndex._novelIndex[nHandle]["T000007"]["level"] == "H2" assert theIndex._novelIndex[nHandle]["T000013"]["level"] == "H3" assert theIndex._novelIndex[nHandle]["T000019"]["level"] == "H4" assert theIndex._novelIndex[nHandle]["T000001"]["title"] == "Title One" assert theIndex._novelIndex[nHandle]["T000007"]["title"] == "Title Two" assert theIndex._novelIndex[nHandle]["T000013"]["title"] == "Title Three" assert theIndex._novelIndex[nHandle]["T000019"]["title"] == "Title Four" assert theIndex._novelIndex[nHandle]["T000001"]["layout"] == "SCENE" assert theIndex._novelIndex[nHandle]["T000007"]["layout"] == "SCENE" assert theIndex._novelIndex[nHandle]["T000013"]["layout"] == "SCENE" assert theIndex._novelIndex[nHandle]["T000019"]["layout"] == "SCENE" assert theIndex._novelIndex[nHandle]["T000001"][ "synopsis"] == "Synopsis One." assert theIndex._novelIndex[nHandle]["T000007"][ "synopsis"] == "Synopsis Two." assert theIndex._novelIndex[nHandle]["T000013"][ "synopsis"] == "Synopsis Three." assert theIndex._novelIndex[nHandle]["T000019"][ "synopsis"] == "Synopsis Four." assert theIndex._novelIndex[nHandle]["T000001"]["cCount"] == 23 assert theIndex._novelIndex[nHandle]["T000007"]["cCount"] == 23 assert theIndex._novelIndex[nHandle]["T000013"]["cCount"] == 27 assert theIndex._novelIndex[nHandle]["T000019"]["cCount"] == 56 assert theIndex._novelIndex[nHandle]["T000001"]["wCount"] == 4 assert theIndex._novelIndex[nHandle]["T000007"]["wCount"] == 4 assert theIndex._novelIndex[nHandle]["T000013"]["wCount"] == 4 assert theIndex._novelIndex[nHandle]["T000019"]["wCount"] == 9 assert theIndex._novelIndex[nHandle]["T000001"]["pCount"] == 1 assert theIndex._novelIndex[nHandle]["T000007"]["pCount"] == 1 assert theIndex._novelIndex[nHandle]["T000013"]["pCount"] == 1 assert theIndex._novelIndex[nHandle]["T000019"]["pCount"] == 3 assert theIndex.scanText(cHandle, ("# Title One\n\n" "@tag: One\n\n" "% synopsis: Synopsis One.\n\n" "Paragraph One.\n\n")) assert theIndex._refIndex[cHandle].get("T000000", None) is not None assert theIndex._refIndex[cHandle].get("T000001", None) is not None assert theIndex._refIndex[cHandle].get("T000002", None) is None assert theIndex._refIndex[cHandle].get("T000003", None) is None assert theIndex._refIndex[cHandle].get("T000004", None) is None assert theIndex._refIndex[cHandle].get("T000005", None) is None assert theIndex._refIndex[cHandle].get("T000006", None) is None assert theIndex._refIndex[cHandle].get("T000007", None) is None assert theIndex._noteIndex[cHandle]["T000001"]["level"] == "H1" assert theIndex._noteIndex[cHandle]["T000001"]["title"] == "Title One" assert theIndex._noteIndex[cHandle]["T000001"]["layout"] == "NOTE" assert theIndex._noteIndex[cHandle]["T000001"][ "synopsis"] == "Synopsis One." assert theIndex._noteIndex[cHandle]["T000001"]["cCount"] == 23 assert theIndex._noteIndex[cHandle]["T000001"]["wCount"] == 4 assert theIndex._noteIndex[cHandle]["T000001"]["pCount"] == 1 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"]["tags"] == ([[ 3, "@pov", "One" ], [5, "@char", "Two"]]) # Page wo/Title theProject.projTree[pHandle].itemLayout = nwItemLayout.PAGE assert theIndex.scanText(pHandle, ("This is a page with some text on it.\n\n")) assert theIndex._novelIndex[pHandle]["T000000"]["level"] == "H0" assert theIndex._novelIndex[pHandle]["T000000"]["title"] == "Untitled Page" assert theIndex._novelIndex[pHandle]["T000000"]["layout"] == "PAGE" assert theIndex._novelIndex[pHandle]["T000000"]["synopsis"] == "" assert theIndex._novelIndex[pHandle]["T000000"]["cCount"] == 36 assert theIndex._novelIndex[pHandle]["T000000"]["wCount"] == 9 assert theIndex._novelIndex[pHandle]["T000000"]["pCount"] == 1 assert pHandle not in theIndex._noteIndex theProject.projTree[pHandle].itemLayout = nwItemLayout.NOTE assert theIndex.scanText(pHandle, ("This is a page with some text on it.\n\n")) assert theIndex._noteIndex[pHandle]["T000000"]["level"] == "H0" assert theIndex._noteIndex[pHandle]["T000000"]["title"] == "Untitled Page" assert theIndex._noteIndex[pHandle]["T000000"]["layout"] == "NOTE" assert theIndex._noteIndex[pHandle]["T000000"]["synopsis"] == "" assert theIndex._noteIndex[pHandle]["T000000"]["cCount"] == 36 assert theIndex._noteIndex[pHandle]["T000000"]["wCount"] == 9 assert theIndex._noteIndex[pHandle]["T000000"]["pCount"] == 1 assert pHandle not in theIndex._novelIndex assert theProject.closeProject()