def testCoreDocument_Methods(mockGUI, nwMinimal):
    """Test other methods of the NWDoc class.
    """
    theProject = NWProject(mockGUI)
    assert theProject.openProject(nwMinimal)
    assert theProject.projPath == nwMinimal

    sHandle = "8c659a11cd429"
    theDoc = NWDoc(theProject, sHandle)
    docPath = os.path.join(nwMinimal, "content", sHandle + ".nwd")

    assert theDoc.readDocument() == "### New Scene\n\n"

    # Check location
    assert theDoc.getFileLocation() == docPath

    # Check the item
    assert theDoc.getCurrentItem() is not None
    assert theDoc.getCurrentItem().itemHandle == sHandle

    # Check the meta
    theName, theParent, theClass, theLayout = theDoc.getMeta()
    assert theName == "New Scene"
    assert theParent == "a6d311a93600a"
    assert theClass == nwItemClass.NOVEL
    assert theLayout == nwItemLayout.DOCUMENT

    # Add meta data garbage
    assert theDoc.writeDocument("%%~ stuff\n### Test File\n\nText ...\n\n")
    assert readFile(docPath) == ("%%~name: New Scene\n"
                                 f"%%~path: a6d311a93600a/{sHandle}\n"
                                 "%%~kind: NOVEL/DOCUMENT\n"
                                 "%%~ stuff\n"
                                 "### Test File\n\n"
                                 "Text ...\n\n")

    assert theDoc.readDocument() == "### Test File\n\nText ...\n\n"
Example #2
0
def testCoreToken_TextOps(monkeypatch, nwMinimal, mockGUI):
    """Test handling files and text in the Tokenizer class.
    """
    theProject = NWProject(mockGUI)
    theProject.projTree.setSeed(42)
    theProject.projLang = "en"
    theProject._loadProjectLocalisation()

    theToken = BareTokenizer(theProject)
    theToken.setKeepMarkdown(True)

    assert theProject.openProject(nwMinimal)
    sHandle = "8c659a11cd429"

    # Set some content to work with

    docText = (
        "### Scene Six\n\n"
        "This is text with _italic text_, some **bold text**, some ~~deleted text~~, "
        "and some **_mixed text_** and **some _nested_ text**.\n\n"
        "#### Replace\n\n"
        "Also, replace <A> and <B>.\n\n")
    docTextR = docText.replace("<A>", "this").replace("<B>", "that")

    nDoc = NWDoc(theProject, sHandle)
    assert nDoc.writeDocument(docText)

    theProject.setAutoReplace({"A": "this", "B": "that"})

    assert theProject.saveProject()

    # Root Heading
    assert theToken.addRootHeading("stuff") is False
    assert theToken.addRootHeading(sHandle) is False

    # First Page
    assert theToken.addRootHeading("7695ce551d265") is True
    assert theToken.theMarkdown[-1] == "# Notes: Plot\n\n"
    assert theToken._theTokens[-1] == (Tokenizer.T_TITLE, 0, "Notes: Plot",
                                       None, Tokenizer.A_CENTRE)

    # Not First Page
    assert theToken.addRootHeading("7695ce551d265") is True
    assert theToken.theMarkdown[-1] == "# Notes: Plot\n\n"
    assert theToken._theTokens[-1] == (Tokenizer.T_TITLE, 0, "Notes: Plot",
                                       None,
                                       Tokenizer.A_CENTRE | Tokenizer.A_PBB)

    # Set Text
    assert theToken.setText("stuff") is False
    assert theToken.setText(sHandle) is True
    assert theToken._theText == docText

    with monkeypatch.context() as mp:
        mp.setattr("novelwriter.constants.nwConst.MAX_DOCSIZE", 100)
        assert theToken.setText(sHandle, docText) is True
        assert theToken._theText == (
            "# ERROR\n\n"
            "Document 'New Scene' is too big (0.00 MB). Skipping.\n\n")

    assert theToken.setText(sHandle, docText) is True
    assert theToken._theText == docText

    assert theToken._isNone is False
    assert theToken._isNovel is True
    assert theToken._isNote is False

    # Pre Processing
    theToken.doPreProcessing()
    assert theToken._theText == docTextR

    # Post Processing
    theToken._theResult = r"This is text with escapes: \** \~~ \__"
    theToken.doPostProcessing()
    assert theToken.theResult == "This is text with escapes: ** ~~ __"

    # Save File
    savePath = os.path.join(nwMinimal, "dump.nwd")
    theToken.saveRawMarkdown(savePath)
    assert readFile(savePath) == ("# Notes: Plot\n\n" "# Notes: Plot\n\n")

    # Ckeck abstract method
    with pytest.raises(NotImplementedError):
        theToken.doConvert()
def testCoreDocument_LoadSave(monkeypatch, mockGUI, nwMinimal):
    """Test loading and saving a document with the NWDoc class.
    """
    theProject = NWProject(mockGUI)
    assert theProject.openProject(nwMinimal) is True
    assert theProject.projPath == nwMinimal

    sHandle = "8c659a11cd429"

    # Read Document
    # =============

    # Not a valid handle
    theDoc = NWDoc(theProject, "stuff")
    assert bool(theDoc) is False
    assert theDoc.readDocument() is None

    # Non-existent handle
    theDoc = NWDoc(theProject, "0000000000000")
    assert theDoc.readDocument() is None
    assert theDoc._currHash is None

    # Cause open() to fail while loading
    with monkeypatch.context() as mp:
        mp.setattr("builtins.open", causeOSError)
        theDoc = NWDoc(theProject, sHandle)
        assert theDoc.readDocument() is None
        assert theDoc.getError() == "OSError: Mock OSError"

    # Load the text
    theDoc = NWDoc(theProject, sHandle)
    assert theDoc.readDocument() == "### New Scene\n\n"

    # Try to open a new (non-existent) file
    nHandle = theProject.projTree.findRoot(nwItemClass.NOVEL)
    assert nHandle is not None
    xHandle = theProject.newFile("New File", nwItemClass.NOVEL, nHandle)
    theDoc = NWDoc(theProject, xHandle)
    assert bool(theDoc) is True
    assert repr(theDoc) == f"<NWDoc handle={xHandle}>"
    assert theDoc.readDocument() == ""

    # Write Document
    # ==============

    # Set handle and save again
    theText = "### Test File\n\nText ...\n\n"
    theDoc = NWDoc(theProject, xHandle)
    assert theDoc.readDocument(xHandle) == ""
    assert theDoc.writeDocument(theText) is True

    # Save again to ensure temp file and previous file is handled
    assert theDoc.writeDocument(theText)

    # Check file content
    docPath = os.path.join(nwMinimal, "content", xHandle + ".nwd")
    assert readFile(docPath) == ("%%~name: New File\n"
                                 f"%%~path: a508bb932959c/{xHandle}\n"
                                 "%%~kind: NOVEL/DOCUMENT\n"
                                 "### Test File\n\n"
                                 "Text ...\n\n")

    # Alter the document on disk and save again
    writeFile(docPath, "blablabla")
    assert theDoc.writeDocument(theText) is False

    # Force the overwrite
    assert theDoc.writeDocument(theText, forceWrite=True) is True

    # Force no meta data
    theDoc._theItem = None
    assert theDoc.writeDocument(theText) is True
    assert readFile(docPath) == theText

    # Cause open() to fail while saving
    with monkeypatch.context() as mp:
        mp.setattr("builtins.open", causeOSError)
        assert theDoc.writeDocument(theText) is False
        assert theDoc.getError() == "OSError: Mock OSError"

    theDoc._docError = ""
    assert theDoc.getError() == ""

    # Cause os.replace() to fail while saving
    with monkeypatch.context() as mp:
        mp.setattr("os.replace", causeOSError)
        assert theDoc.writeDocument(theText) is False
        assert theDoc.getError() == "OSError: Mock OSError"

    theDoc._docError = ""
    assert theDoc.getError() == ""

    # Saving with no handle
    theDoc._docHandle = None
    assert theDoc.writeDocument(theText) is False

    # Delete Document
    # ===============

    # Delete the last document
    theDoc = NWDoc(theProject, "stuff")
    assert theDoc.deleteDocument() is False
    assert os.path.isfile(docPath)

    # Cause the delete to fail
    with monkeypatch.context() as mp:
        mp.setattr("os.unlink", causeOSError)
        theDoc = NWDoc(theProject, xHandle)
        assert theDoc.deleteDocument() is False
        assert theDoc.getError() == "OSError: Mock OSError"

    # Make the delete pass
    theDoc = NWDoc(theProject, xHandle)
    assert theDoc.deleteDocument() is True
    assert not os.path.isfile(docPath)