Пример #1
0
def testCoreProject_AccessItems(nwMinimal, mockGUI):
    """Test helper functions for the project folder.
    """
    theProject = NWProject(mockGUI)
    theProject.openProject(nwMinimal)

    # Move Novel ROOT to after its files
    oldOrder = [
        "a508bb932959c",  # ROOT: Novel
        "a35baf2e93843",  # FILE: Title Page
        "a6d311a93600a",  # FOLDER: New Chapter
        "f5ab3e30151e1",  # FILE: New Chapter
        "8c659a11cd429",  # FILE: New Scene
        "7695ce551d265",  # ROOT: Plot
        "afb3043c7b2b3",  # ROOT: Characters
        "9d5247ab588e0",  # ROOT: World
    ]
    newOrder = [
        "a35baf2e93843",  # FILE: Title Page
        "f5ab3e30151e1",  # FILE: New Chapter
        "8c659a11cd429",  # FILE: New Scene
        "a6d311a93600a",  # FOLDER: New Chapter
        "a508bb932959c",  # ROOT: Novel
        "7695ce551d265",  # ROOT: Plot
        "afb3043c7b2b3",  # ROOT: Characters
        "9d5247ab588e0",  # ROOT: World
    ]
    assert theProject.projTree.handles() == oldOrder
    assert theProject.setTreeOrder(newOrder)
    assert theProject.projTree.handles() == newOrder

    # Add a non-existing item
    theProject.projTree._treeOrder.append("01234567789abc")

    # Add an item with a non-existent parent
    nHandle = theProject.newFile("Test File", nwItemClass.NOVEL,
                                 "a6d311a93600a")
    theProject.projTree[nHandle].setParent("cba9876543210")
    assert theProject.projTree[nHandle].itemParent == "cba9876543210"

    retOrder = []
    for tItem in theProject.getProjectItems():
        retOrder.append(tItem.itemHandle)

    assert retOrder == [
        "a508bb932959c",  # ROOT: Novel
        "7695ce551d265",  # ROOT: Plot
        "afb3043c7b2b3",  # ROOT: Characters
        "9d5247ab588e0",  # ROOT: World
        nHandle,  # FILE: Test File
        "a35baf2e93843",  # FILE: Title Page
        "a6d311a93600a",  # FOLDER: New Chapter
        "f5ab3e30151e1",  # FILE: New Chapter
        "8c659a11cd429",  # FILE: New Scene
    ]
    assert theProject.projTree[nHandle].itemParent is None
Пример #2
0
def testCoreProject_Methods(monkeypatch, nwMinimal, mockGUI, tmpDir):
    """Test other project class methods and functions.
    """
    theProject = NWProject(mockGUI)
    theProject.projTree.setSeed(42)
    assert theProject.openProject(nwMinimal)
    assert theProject.projPath == nwMinimal

    # Setting project path
    assert theProject.setProjectPath(None)
    assert theProject.projPath is None
    assert theProject.setProjectPath("")
    assert theProject.projPath is None
    assert theProject.setProjectPath("~")
    assert theProject.projPath == os.path.expanduser("~")

    # Create a new folder and populate it
    projPath = os.path.join(nwMinimal, "mock1")
    assert theProject.setProjectPath(projPath, newProject=True)

    # Make os.mkdir fail
    monkeypatch.setattr("os.mkdir", causeOSError)
    projPath = os.path.join(nwMinimal, "mock2")
    assert not theProject.setProjectPath(projPath, newProject=True)

    # Set back
    assert theProject.setProjectPath(nwMinimal)

    # Project Name
    assert theProject.setProjectName("  A Name ")
    assert theProject.projName == "A Name"

    # Project Title
    assert theProject.setBookTitle("  A Title ")
    assert theProject.bookTitle == "A Title"

    # Project Authors
    # Check that the list is cleaned up and that it can be extracted as
    # a properly formatted string, depending on number of names
    assert not theProject.setBookAuthors([])
    assert theProject.setBookAuthors(" Jane Doe \n John Doh \n ")
    assert theProject.bookAuthors == ["Jane Doe", "John Doh"]

    assert theProject.setBookAuthors("")
    assert theProject.getAuthors() == ""

    assert theProject.setBookAuthors("Jane Doe")
    assert theProject.getAuthors() == "Jane Doe"

    assert theProject.setBookAuthors("Jane Doe\nJohn Doh")
    assert theProject.getAuthors() == "Jane Doe and John Doh"

    assert theProject.setBookAuthors("Jane Doe\nJohn Doh\nBod Owens")
    assert theProject.getAuthors() == "Jane Doe, John Doh and Bod Owens"

    # Edit Time
    theProject.editTime = 1234
    theProject.projOpened = 1600000000
    with monkeypatch.context() as mp:
        mp.setattr("novelwriter.core.project.time", lambda: 1600005600)
        assert theProject.getCurrentEditTime() == 6834

    # Trash folder
    # Should create on first call, and just returned on later calls
    assert theProject.projTree["73475cb40a568"] is None
    assert theProject.trashFolder() == "73475cb40a568"
    assert theProject.trashFolder() == "73475cb40a568"

    # Project backup
    assert theProject.doBackup is True
    assert theProject.setProjBackup(False)
    assert theProject.doBackup is False

    assert not theProject.setProjBackup(True)
    theProject.mainConf.backupPath = tmpDir
    assert theProject.setProjBackup(True)

    assert theProject.setProjectName("")
    assert not theProject.setProjBackup(True)
    assert theProject.setProjectName("A Name")
    assert theProject.setProjBackup(True)

    # Spell check
    theProject.projChanged = False
    assert theProject.setSpellCheck(True)
    assert not theProject.setSpellCheck(False)
    assert theProject.projChanged

    # Spell language
    theProject.projChanged = False
    assert theProject.setSpellLang(None)
    assert theProject.projSpell is None
    assert theProject.setSpellLang("None")
    assert theProject.projSpell is None
    assert theProject.setSpellLang("en_GB")
    assert theProject.projSpell == "en_GB"
    assert theProject.projChanged

    # Project Language
    theProject.projChanged = False
    theProject.projLang = "en"
    assert theProject.setProjectLang(None) is True
    assert theProject.projLang is None
    assert theProject.setProjectLang("en_GB") is True
    assert theProject.projLang == "en_GB"

    # Automatic outline update
    theProject.projChanged = False
    assert theProject.setAutoOutline(True)
    assert not theProject.setAutoOutline(False)
    assert theProject.projChanged

    # Last edited
    theProject.projChanged = False
    assert theProject.setLastEdited("0123456789abc")
    assert theProject.lastEdited == "0123456789abc"
    assert theProject.projChanged

    # Last viewed
    theProject.projChanged = False
    assert theProject.setLastViewed("0123456789abc")
    assert theProject.lastViewed == "0123456789abc"
    assert theProject.projChanged

    # Autoreplace
    theProject.projChanged = False
    assert theProject.setAutoReplace({"A": "B", "C": "D"})
    assert theProject.autoReplace == {"A": "B", "C": "D"}
    assert theProject.projChanged

    # Change project tree order
    oldOrder = [
        "a508bb932959c",
        "a35baf2e93843",
        "a6d311a93600a",
        "f5ab3e30151e1",
        "8c659a11cd429",
        "7695ce551d265",
        "afb3043c7b2b3",
        "9d5247ab588e0",
        "73475cb40a568",
    ]
    newOrder = [
        "f5ab3e30151e1",
        "8c659a11cd429",
        "7695ce551d265",
        "a508bb932959c",
        "a35baf2e93843",
        "a6d311a93600a",
        "afb3043c7b2b3",
        "9d5247ab588e0",
    ]
    assert theProject.projTree.handles() == oldOrder
    assert theProject.setTreeOrder(newOrder)
    assert theProject.projTree.handles() == newOrder
    assert theProject.setTreeOrder(oldOrder)
    assert theProject.projTree.handles() == oldOrder

    # Change status
    theProject.projTree["a35baf2e93843"].setStatus("Finished")
    theProject.projTree["a6d311a93600a"].setStatus("Draft")
    theProject.projTree["f5ab3e30151e1"].setStatus("Note")
    theProject.projTree["8c659a11cd429"].setStatus("Finished")
    newList = [
        ("New", 1, 1, 1, "New"),
        ("Draft", 2, 2, 2, "Note"),  # These are swapped
        ("Note", 3, 3, 3, "Draft"),  # These are swapped
        ("Edited", 4, 4, 4, "Finished"),  # Renamed
        ("Finished", 5, 5, 5, None),  # New, with reused name
    ]
    assert theProject.setStatusColours(newList)
    assert theProject.statusItems._theLabels == [
        "New", "Draft", "Note", "Edited", "Finished"
    ]
    assert theProject.statusItems._theColours == [(1, 1, 1), (2, 2, 2),
                                                  (3, 3, 3), (4, 4, 4),
                                                  (5, 5, 5)]
    assert theProject.projTree[
        "a35baf2e93843"].itemStatus == "Edited"  # Renamed
    assert theProject.projTree["a6d311a93600a"].itemStatus == "Note"  # Swapped
    assert theProject.projTree["f5ab3e30151e1"].itemStatus == "Draft"  # Swapped
    assert theProject.projTree[
        "8c659a11cd429"].itemStatus == "Edited"  # Renamed

    # Change importance
    fHandle = theProject.newFile("Jane Doe", nwItemClass.CHARACTER,
                                 "afb3043c7b2b3")
    theProject.projTree[fHandle].setImport("Main")
    newList = [
        ("New", 1, 1, 1, "New"),
        ("Minor", 2, 2, 2, "Minor"),
        ("Major", 3, 3, 3, "Major"),
        ("Min", 4, 4, 4, "Main"),
        ("Max", 5, 5, 5, None),
    ]
    assert theProject.setImportColours(newList)
    assert theProject.importItems._theLabels == [
        "New", "Minor", "Major", "Min", "Max"
    ]
    assert theProject.importItems._theColours == [(1, 1, 1), (2, 2, 2),
                                                  (3, 3, 3), (4, 4, 4),
                                                  (5, 5, 5)]
    assert theProject.projTree[fHandle].itemImport == "Min"

    # Check status counts
    assert theProject.statusItems._theCounts == [0, 0, 0, 0, 0]
    assert theProject.importItems._theCounts == [0, 0, 0, 0, 0]
    theProject.countStatus()
    assert theProject.statusItems._theCounts == [1, 1, 1, 2, 0]
    assert theProject.importItems._theCounts == [3, 0, 0, 1, 0]

    # Session stats
    theProject.currWCount = 200
    theProject.lastWCount = 100
    with monkeypatch.context() as mp:
        mp.setattr("os.path.isdir", lambda *a, **k: False)
        assert not theProject._appendSessionStats(idleTime=0)

    # Block open
    with monkeypatch.context() as mp:
        mp.setattr("builtins.open", causeOSError)
        assert not theProject._appendSessionStats(idleTime=0)

    # Write entry
    assert theProject.projMeta == os.path.join(nwMinimal, "meta")
    statsFile = os.path.join(theProject.projMeta, nwFiles.SESS_STATS)

    theProject.projOpened = 1600002000
    theProject.currNovelWC = 200
    theProject.currNotesWC = 100

    with monkeypatch.context() as mp:
        mp.setattr("novelwriter.core.project.time", lambda: 1600005600)
        assert theProject._appendSessionStats(idleTime=99)

    assert readFile(statsFile) == (
        "# Offset 100\n"
        "# Start Time         End Time                Novel     Notes      Idle\n"
        "%s  %s       200       100        99\n") % (
            formatTimeStamp(1600002000), formatTimeStamp(1600005600))

    # Pack XML Value
    xElem = etree.Element("element")
    theProject._packProjectValue(xElem, "A", "B", allowNone=False)
    assert etree.tostring(xElem, pretty_print=False,
                          encoding="utf-8") == (b"<element><A>B</A></element>")

    xElem = etree.Element("element")
    theProject._packProjectValue(xElem, "A", "", allowNone=False)
    assert etree.tostring(xElem, pretty_print=False,
                          encoding="utf-8") == (b"<element/>")

    # Pack XML Key/Value
    xElem = etree.Element("element")
    theProject._packProjectKeyValue(xElem, "item", {"A": "B", "C": "D"})
    assert etree.tostring(xElem, pretty_print=False,
                          encoding="utf-8") == (b"<element>"
                                                b"<item>"
                                                b"<entry key=\"A\">B</entry>"
                                                b"<entry key=\"C\">D</entry>"
                                                b"</item>"
                                                b"</element>")