Coverage of index class 100%

This commit is contained in:
Veronica K. B. Olsen
2020-09-30 22:57:00 +02:00
parent 9bf50cae34
commit 86d5a6f6b2
3 changed files with 702 additions and 11 deletions
+10 -11
View File
@@ -29,8 +29,7 @@ import nw
import logging
import json
import os
from time import time
import time
from nw.constants import (
nwFiles, nwKeyWords, nwItemType, nwItemClass, nwItemLayout, nwAlert
@@ -177,7 +176,7 @@ class NWIndex():
if "textCounts" in theData.keys():
self.textCounts = theData["textCounts"]
nowTime = round(time())
nowTime = round(time.time())
self.timeNovel = nowTime
self.timeNote = nowTime
self.timeIndex = nowTime
@@ -305,7 +304,7 @@ class NWIndex():
self.refIndex[tHandle] = {}
self.refIndex[tHandle]["T000000"] = {
"tags" : [],
"updated" : round(time()),
"updated" : round(time.time()),
}
if itemLayout == nwItemLayout.NOTE:
self.noteIndex[tHandle] = {}
@@ -360,7 +359,7 @@ class NWIndex():
self._indexWordCounts(tHandle, isNovel, lastText, nTitle)
# Update timestamps for index changes
nowTime = round(time())
nowTime = round(time.time())
self.timeIndex = nowTime
if isNovel:
self.timeNovel = nowTime
@@ -395,7 +394,7 @@ class NWIndex():
sTitle = "T%06d" % nLine
self.refIndex[tHandle][sTitle] = {
"tags" : [],
"updated" : round(time()),
"updated" : round(time.time()),
}
theData = {
"level" : hDepth,
@@ -405,7 +404,7 @@ class NWIndex():
"cCount" : 0,
"wCount" : 0,
"pCount" : 0,
"updated" : round(time()),
"updated" : round(time.time()),
}
if hText != "":
@@ -429,14 +428,14 @@ class NWIndex():
self.novelIndex[tHandle][sTitle]["cCount"] = cC
self.novelIndex[tHandle][sTitle]["wCount"] = wC
self.novelIndex[tHandle][sTitle]["pCount"] = pC
self.novelIndex[tHandle][sTitle]["updated"] = round(time())
self.novelIndex[tHandle][sTitle]["updated"] = round(time.time())
else:
if tHandle in self.noteIndex:
if sTitle in self.noteIndex[tHandle]:
self.noteIndex[tHandle][sTitle]["cCount"] = cC
self.noteIndex[tHandle][sTitle]["wCount"] = wC
self.noteIndex[tHandle][sTitle]["pCount"] = pC
self.noteIndex[tHandle][sTitle]["updated"] = round(time())
self.noteIndex[tHandle][sTitle]["updated"] = round(time.time())
return
def _indexSynopsis(self, tHandle, isNovel, theText, nTitle):
@@ -447,12 +446,12 @@ class NWIndex():
if tHandle in self.novelIndex:
if sTitle in self.novelIndex[tHandle]:
self.novelIndex[tHandle][sTitle]["synopsis"] = theText
self.novelIndex[tHandle][sTitle]["updated"] = round(time())
self.novelIndex[tHandle][sTitle]["updated"] = round(time.time())
else:
if tHandle in self.noteIndex:
if sTitle in self.noteIndex[tHandle]:
self.noteIndex[tHandle][sTitle]["synopsis"] = theText
self.noteIndex[tHandle][sTitle]["updated"] = round(time())
self.noteIndex[tHandle][sTitle]["updated"] = round(time.time())
return
def _indexNoteRef(self, tHandle, aLine, nLine, nTitle):
+560
View File
@@ -0,0 +1,560 @@
{
"tagIndex": {
"Bod": [
3,
"4c4f28287af27",
"CHARACTER",
"T000001"
],
"Main": [
3,
"2426c6f0ca922",
"PLOT",
"T000001"
],
"Europe": [
3,
"04468803b92e1",
"WORLD",
"T000001"
]
},
"refIndex": {
"7a992350f3eb6": {
"T000000": {
"tags": [],
"updated": 123
},
"T000001": {
"tags": [],
"updated": 123
}
},
"8c58a65414c23": {
"T000000": {
"tags": [],
"updated": 123
}
},
"88d59a277361b": {
"T000000": {
"tags": [],
"updated": 123
},
"T000001": {
"tags": [],
"updated": 123
}
},
"db7e733775d4d": {
"T000000": {
"tags": [],
"updated": 123
},
"T000001": {
"tags": [],
"updated": 123
}
},
"fb609cd8319dc": {
"T000000": {
"tags": [],
"updated": 123
},
"T000001": {
"tags": [
[
3,
"@pov",
"Bod"
],
[
4,
"@plot",
"Main"
],
[
5,
"@location",
"Europe"
]
],
"updated": 123
}
},
"88243afbe5ed8": {
"T000000": {
"tags": [],
"updated": 123
},
"T000001": {
"tags": [
[
3,
"@pov",
"Bod"
],
[
4,
"@plot",
"Main"
],
[
5,
"@location",
"Europe"
]
],
"updated": 123
},
"T000013": {
"tags": [],
"updated": 123
}
},
"f96ec11c6a3da": {
"T000000": {
"tags": [],
"updated": 123
},
"T000001": {
"tags": [
[
3,
"@pov",
"Bod"
],
[
4,
"@plot",
"Main"
],
[
5,
"@location",
"Europe"
]
],
"updated": 123
},
"T000015": {
"tags": [],
"updated": 123
}
},
"846352075de7d": {
"T000000": {
"tags": [],
"updated": 123
},
"T000001": {
"tags": [],
"updated": 123
}
},
"441420a886d82": {
"T000000": {
"tags": [],
"updated": 123
},
"T000001": {
"tags": [
[
3,
"@pov",
"Bod"
],
[
4,
"@plot",
"Main"
],
[
5,
"@location",
"Europe"
]
],
"updated": 123
}
},
"eb103bc70c90c": {
"T000000": {
"tags": [],
"updated": 123
},
"T000001": {
"tags": [
[
3,
"@pov",
"Bod"
],
[
4,
"@plot",
"Main"
],
[
5,
"@location",
"Europe"
]
],
"updated": 123
}
},
"f8c0562e50f1b": {
"T000000": {
"tags": [],
"updated": 123
},
"T000001": {
"tags": [
[
3,
"@pov",
"Bod"
],
[
4,
"@plot",
"Main"
],
[
5,
"@location",
"Europe"
]
],
"updated": 123
}
},
"47666c91c7ccf": {
"T000000": {
"tags": [],
"updated": 123
},
"T000001": {
"tags": [
[
3,
"@pov",
"Bod"
],
[
4,
"@plot",
"Main"
],
[
5,
"@location",
"Europe"
]
],
"updated": 123
}
},
"4c4f28287af27": {
"T000000": {
"tags": [],
"updated": 123
},
"T000001": {
"tags": [],
"updated": 123
}
},
"2426c6f0ca922": {
"T000000": {
"tags": [],
"updated": 123
},
"T000001": {
"tags": [],
"updated": 123
}
},
"04468803b92e1": {
"T000000": {
"tags": [],
"updated": 123
},
"T000001": {
"tags": [],
"updated": 123
}
}
},
"novelIndex": {
"7a992350f3eb6": {
"T000001": {
"level": "H1",
"title": "Lorem Ipsum",
"layout": "TITLE",
"synopsis": "",
"cCount": 230,
"wCount": 40,
"pCount": 3,
"updated": 123
}
},
"8c58a65414c23": {},
"88d59a277361b": {
"T000001": {
"level": "H2",
"title": "Prologue",
"layout": "UNNUMBERED",
"synopsis": "Explanation from the lipsum.com website.",
"cCount": 584,
"wCount": 92,
"pCount": 1,
"updated": 123
}
},
"db7e733775d4d": {
"T000001": {
"level": "H1",
"title": "Act One",
"layout": "PARTITION",
"synopsis": "",
"cCount": 35,
"wCount": 6,
"pCount": 1,
"updated": 123
}
},
"fb609cd8319dc": {
"T000001": {
"level": "H2",
"title": "Chapter One",
"layout": "CHAPTER",
"synopsis": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque at aliquam quam.",
"cCount": 419,
"wCount": 67,
"pCount": 1,
"updated": 123
}
},
"88243afbe5ed8": {
"T000001": {
"level": "H3",
"title": "Scene One",
"layout": "SCENE",
"synopsis": "Aenean ut placerat velit. Etiam laoreet ullamcorper risus, eget lobortis enim scelerisque non. Suspendisse id maximus nunc, et mollis sapien. Curabitur vel semper sapien, non pulvinar dolor. Etiam finibus nisi vel mi molestie consectetur.",
"cCount": 1197,
"wCount": 174,
"pCount": 2,
"updated": 123
},
"T000013": {
"level": "H4",
"title": "Scene One, Section Two",
"layout": "SCENE",
"synopsis": "",
"cCount": 1561,
"wCount": 230,
"pCount": 2,
"updated": 123
}
},
"f96ec11c6a3da": {
"T000001": {
"level": "H3",
"title": "Scene Two",
"layout": "SCENE",
"synopsis": "Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Integer sapien nulla, dictum at lacus a, dignissim consectetur dolor. Nunc vel eleifend lacus, eu dapibus orci.",
"cCount": 2034,
"wCount": 299,
"pCount": 3,
"updated": 123
},
"T000015": {
"level": "H4",
"title": "Scene Two, Section Two",
"layout": "SCENE",
"synopsis": "",
"cCount": 2009,
"wCount": 301,
"pCount": 3,
"updated": 123
}
},
"846352075de7d": {
"T000001": {
"level": "H2",
"title": "Why do we use it?",
"layout": "BOOK",
"synopsis": "",
"cCount": 630,
"wCount": 109,
"pCount": 1,
"updated": 123
}
},
"441420a886d82": {
"T000001": {
"level": "H2",
"title": "Chapter Two",
"layout": "CHAPTER",
"synopsis": "Curabitur a elit posuere, varius ex et, convallis neque. Phasellus sagittis pharetra sem vitae dapibus. Curabitur varius lorem non pulvinar congue.",
"cCount": 477,
"wCount": 70,
"pCount": 1,
"updated": 123
}
},
"eb103bc70c90c": {
"T000001": {
"level": "H3",
"title": "Scene Three",
"layout": "SCENE",
"synopsis": "Aenean ut libero ut lectus porttitor rhoncus vel et massa. Nam pretium, nibh et varius vehicula, urna metus blandit eros, euismod pharetra diam diam et libero. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.",
"cCount": 3006,
"wCount": 439,
"pCount": 4,
"updated": 123
}
},
"f8c0562e50f1b": {
"T000001": {
"level": "H3",
"title": "Scene Four",
"layout": "SCENE",
"synopsis": "Nam tempor blandit magna laoreet aliquet. Vestibulum auctor posuere leo, ac gravida nisi rhoncus varius. Aenean posuere dolor vitae condimentum volutpat. Donec egestas volutpat risus, quis luctus justo.",
"cCount": 3839,
"wCount": 563,
"pCount": 6,
"updated": 123
}
},
"47666c91c7ccf": {
"T000001": {
"level": "H3",
"title": "Scene Five",
"layout": "SCENE",
"synopsis": "Praesent eget est porta, dictum ante in, egestas risus. Mauris risus mauris, consequat aliquam mauris et, feugiat iaculis ipsum. Aliquam arcu ipsum, fermentum ut arcu sed, lobortis euismod sem. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.",
"cCount": 3644,
"wCount": 543,
"pCount": 5,
"updated": 123
}
}
},
"noteIndex": {
"4c4f28287af27": {
"T000001": {
"level": "H1",
"title": "Nobody Owens",
"layout": "NOTE",
"synopsis": "",
"cCount": 1864,
"wCount": 284,
"pCount": 3,
"updated": 123
}
},
"2426c6f0ca922": {
"T000001": {
"level": "H1",
"title": "Main Plot",
"layout": "NOTE",
"synopsis": "",
"cCount": 1369,
"wCount": 195,
"pCount": 2,
"updated": 123
}
},
"04468803b92e1": {
"T000001": {
"level": "H1",
"title": "Ancient Europe",
"layout": "NOTE",
"synopsis": "",
"cCount": 1770,
"wCount": 259,
"pCount": 3,
"updated": 123
}
}
},
"textCounts": {
"7a992350f3eb6": [
230,
40,
3
],
"8c58a65414c23": [
1058,
176,
2
],
"88d59a277361b": [
584,
92,
1
],
"db7e733775d4d": [
35,
6,
1
],
"fb609cd8319dc": [
419,
67,
1
],
"88243afbe5ed8": [
2758,
404,
4
],
"f96ec11c6a3da": [
4043,
600,
6
],
"846352075de7d": [
630,
109,
1
],
"441420a886d82": [
477,
70,
1
],
"eb103bc70c90c": [
3006,
439,
4
],
"f8c0562e50f1b": [
3839,
563,
6
],
"47666c91c7ccf": [
3644,
543,
5
],
"4c4f28287af27": [
1864,
284,
3
],
"2426c6f0ca922": [
1369,
195,
2
],
"04468803b92e1": [
1770,
259,
3
]
}
}
+132
View File
@@ -3,11 +3,143 @@
"""
import pytest
import time
import os
import json
from shutil import copyfile
from nwtools import cmpFiles
from nw.core.project import NWProject
from nw.core.index import NWIndex
from nw.constants import nwItemClass, nwItemLayout
@pytest.mark.project
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)
theProject.mainConf.debugInfo = True
monkeypatch.setattr(time, "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, "dumps", 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, "loads", 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)
@pytest.mark.project
def testIndexScanThis(nwMinimal, nwDummy):
"""Test the tag scanner function scanThis.