Exemplo n.º 1
0
def fillAspect(aspectj_setup_dir, monitor_setup_dir, gen_monitor_setup_dir):
    """
    Fills the user-defined parts of a generated .aj file.

    The file should be called unittestMonitorAspect.aj file.

    Args:
        aspectj_setup_dir (str): The destination directory for the
            filled .aj file.

        monitor_setup_dir (str): Input directory that contains two files:
            * import.txt: should contain the code that replaces the
              "// add your own imports." comment in the .aj file.
            * ajcode.txt: should contain the code that replaces the
              "// Implement your code here." comment in the .aj file.

        gen_monitor_dir (str): The input directory, which must a
            a single unittestMonitorAspect.aj file.
    """
    tools.progress("Fill in AspectJ template")
    aspect_file_name = "unittestMonitorAspect.aj"
    aspect_file_path = os.path.join(gen_monitor_setup_dir, aspect_file_name)
    aspectContent = tools.readFile(aspect_file_path)
    aspectContent = aspectContent.replace(
        "// add your own imports.",
        tools.readFile(os.path.join(monitor_setup_dir, "import.txt")))
    aspectContent = aspectContent.replace(
        "// Implement your code here.",
        tools.readFile(os.path.join(monitor_setup_dir, "ajcode.txt")))
    tools.writeFile(os.path.join(aspectj_setup_dir, aspect_file_name),
                    aspectContent)
Exemplo n.º 2
0
def importPapers(file):
    papers = []
    dataRaw = tools.readFile(file)
    dataReady = toPaperData(dataRaw)
    papers = loadDataToPaper(dataReady)
    print("+importPapers+ total number of papers found:", len(papers))
    return papers
Exemplo n.º 3
0
def addRvmExceptions(rvm_file_path):
    """
    Changes the getState functions to throw an exception with the state name.

    The input file will be changed in-place.

    The getState function should have the following format:
    private void somename_getState() throws GotoStmtException, RaiseStmtException {
    }

    The resulting getState function will look like this:
    private void somename_getState() throws GotoStmtException, RaiseStmtException {
        throw new StateNameException(state.getName());
    }


    Args:
        rvm_file_path (str): The path to the rvm file.
    """
    rvm = re.sub(
        r"([ ]*)private void ([a-zA-Z_0-9]+)_getState\(\) throws GotoStmtException, RaiseStmtException \{",
        r"""\1private void \2_getState() throws GotoStmtException, RaiseStmtException, StateNameException {
\1    throw new StateNameException(state.getName());""",
        tools.readFile(rvm_file_path))
    tools.writeFile(rvm_file_path, rvm)
Exemplo n.º 4
0
def testCoreProject_LockFile(monkeypatch, fncDir, dummyGUI):
    """Test lock file functions for the project folder.
    """
    theProject = NWProject(dummyGUI)

    lockFile = os.path.join(fncDir, nwFiles.PROJ_LOCK)

    # No project
    assert theProject._writeLockFile() is False
    assert theProject._readLockFile() == ["ERROR"]
    assert theProject._clearLockFile() is False

    theProject.projPath = fncDir
    theProject.mainConf.hostName = "TestHost"
    theProject.mainConf.osType = "TestOS"
    theProject.mainConf.kernelVer = "1.0"

    # Block open
    monkeypatch.setattr("builtins.open", causeOSError)
    assert theProject._writeLockFile() is False
    monkeypatch.undo()

    # Write lock file
    monkeypatch.setattr("nw.core.project.time", lambda: 123.4)
    assert theProject._writeLockFile() is True
    monkeypatch.undo()
    assert readFile(lockFile) == "TestHost\nTestOS\n1.0\n123\n"

    # Block open
    monkeypatch.setattr("builtins.open", causeOSError)
    assert theProject._readLockFile() == ["ERROR"]
    monkeypatch.undo()

    # Read lock file
    assert theProject._readLockFile() == ["TestHost", "TestOS", "1.0", "123"]

    # Block unlink
    monkeypatch.setattr("os.unlink", causeOSError)
    assert os.path.isfile(lockFile)
    assert theProject._clearLockFile() is False
    assert os.path.isfile(lockFile)
    monkeypatch.undo()

    # Clear file
    assert os.path.isfile(lockFile)
    assert theProject._clearLockFile() is True
    assert not os.path.isfile(lockFile)

    # Read again, no file
    assert theProject._readLockFile() == []

    # Read an invalid lock file
    writeFile(lockFile, "A\nB")
    assert theProject._readLockFile() == ["ERROR"]
    assert theProject._clearLockFile() is True
Exemplo n.º 5
0
def testCoreSpell_Super(monkeypatch, tmpDir, tmpConf):
    """Test the spell checker super class
    """
    wList = os.path.join(tmpDir, "wordlist.txt")
    writeFile(wList, "a_word\nb_word\nc_word\n")

    spChk = NWSpellCheck()
    spChk.mainConf = tmpConf

    # Check that dummy functions return results that reflects that spell
    # checking is effectively disabled
    assert spChk.setLanguage("", "") is None
    assert spChk.checkWord("")
    assert spChk.suggestWords("") == []
    assert spChk.listDictionaries() == []
    assert spChk.describeDict() == ("", "")

    # Check language info
    assert NWSpellCheck.expandLanguage("en") == "English"
    assert NWSpellCheck.expandLanguage("en_GB") == "English (GB)"

    # Add a word to the user's dictionary
    assert spChk._readProjectDictionary("dummy") is False
    monkeypatch.setattr("builtins.open", causeOSError)
    assert spChk._readProjectDictionary(wList) is False
    monkeypatch.undo()
    assert spChk._readProjectDictionary(wList) is True
    assert spChk.projectDict == wList

    # Cannot write to file
    monkeypatch.setattr("builtins.open", causeOSError)
    assert spChk.addWord("d_word") is False
    monkeypatch.undo()
    assert readFile(wList) == "a_word\nb_word\nc_word\n"

    # First time, OK
    assert spChk.addWord("d_word") is True
    assert readFile(wList) == "a_word\nb_word\nc_word\nd_word\n"

    # But not added twice
    assert spChk.addWord("d_word") is False
    assert readFile(wList) == "a_word\nb_word\nc_word\nd_word\n"
Exemplo n.º 6
0
def readSensors(proxy):    
    #output = proxy.shell(['sensors','-A'])
    output = readFile('../../tmp/sensors-out.txt')
    blocks = output.split('\n\n') #split in blocks of text
    modules = []
    
    for block in blocks:
        if len(block) > 0:
            module = readModule(block)
            modules.append(module)
    return modules
Exemplo n.º 7
0
def readSensors(proxy):
    #output = proxy.shell(['sensors','-A'])
    output = readFile('../../tmp/sensors-out.txt')
    blocks = output.split('\n\n')  #split in blocks of text
    modules = []

    for block in blocks:
        if len(block) > 0:
            module = readModule(block)
            modules.append(module)
    return modules
Exemplo n.º 8
0
def fillAspect(aspectj_dir, gen_monitor_dir):
    """
    Fills the user-defined parts of a generated .aj file.

    The current directory should contain two files:
        * import.txt: should contain the code that replaces the
          "// add your own imports." comment in the .aj file.
        * ajcode.txt: should contain the code that replaces the
          "// Implement your code here." comment in the .aj file.
    
    The fillAspect function replaces the comments mentioned above in
    the .aj file, and copies the result to the destination directory.

    Args:
        aspectj_dir (str): The destination directory for the
            filled .aj file.

        gen_monitor_dir (str): The input directory, which must contain
            a single .aj file

    Raises:
        Exception if the input directory does not contain exactly
            one .aj file.
    """
    tools.progress("Fill in AspectJ template")
    aspect_file_paths = glob.glob(os.path.join(gen_monitor_dir, "*.aj"))
    if len(aspect_file_paths) != 1:
        raise Exception("Expected a single aspectJ template")
    aspect_file_path = aspect_file_paths[0]
    aspectContent = tools.readFile(aspect_file_path)
    aspectContent = aspectContent.replace("// add your own imports.",
                                          tools.readFile("import.txt"))
    aspectContent = aspectContent.replace("// Implement your code here.",
                                          tools.readFile("ajcode.txt"))
    aspect_file_name = os.path.basename(aspect_file_path)
    tools.writeFile(os.path.join(aspectj_dir, aspect_file_name), aspectContent)
Exemplo n.º 9
0
def testCoreToMarkdown_Complex(mockGUI, fncDir):
    """Test the save method of the ToMarkdown class.
    """
    theProject = NWProject(mockGUI)
    theMD = ToMarkdown(theProject)
    theMD._isNovel = True

    # Build Project
    # =============

    docText = [
        "# My Novel\n**By Jane Doh**\n",
        "## Chapter 1\n\nThe text of chapter one.\n",
        "### Scene 1\n\nThe text of scene one.\n",
        "#### A Section\n\nMore text in scene one.\n",
        "## Chapter 2\n\nThe text of chapter two.\n",
        "### Scene 2\n\nThe text of scene two.\n",
        "#### A Section\n\n\tMore text in scene two.\n",
    ]
    resText = [
        "# My Novel\n\n**By Jane Doh**\n\n",
        "## Chapter 1\n\nThe text of chapter one.\n\n",
        "### Scene 1\n\nThe text of scene one.\n\n",
        "#### A Section\n\nMore text in scene one.\n\n",
        "## Chapter 2\n\nThe text of chapter two.\n\n",
        "### Scene 2\n\nThe text of scene two.\n\n",
        "#### A Section\n\n\tMore text in scene two.\n\n",
    ]

    for i in range(len(docText)):
        theMD._theText = docText[i]
        theMD.doPreProcessing()
        theMD.tokenizeText()
        theMD.doConvert()
        assert theMD.theResult == resText[i]

    assert theMD.fullMD == resText
    assert theMD.getFullResultSize() == len("".join(resText))

    theMD.replaceTabs(nSpaces=4, spaceChar=" ")
    resText[6] = "#### A Section\n\n    More text in scene two.\n\n"

    # Check File
    # ==========

    saveFile = os.path.join(fncDir, "outFile.md")
    theMD.saveMarkdown(saveFile)
    assert readFile(saveFile) == "".join(resText)
Exemplo n.º 10
0
def testCoreTree_ToCFile(monkeypatch, mockGUI, mockItems, tmpDir):
    """Test writing the ToC.txt file.
    """
    theProject = NWProject(mockGUI)
    theTree = NWTree(theProject)

    for tHandle, pHandle, nwItem in mockItems:
        theTree.append(tHandle, pHandle, nwItem)
        theTree.updateItemData(tHandle)

    assert len(theTree) == len(mockItems)
    theTree._treeOrder.append("stuff")

    def mockIsFile(fileName):
        """Return True for items that are files in novelWriter and
        should thus also be files in the project folder structure.
        """
        dItem = theTree[fileName[8:21]]
        assert dItem is not None
        return dItem.itemType == nwItemType.FILE

    monkeypatch.setattr("os.path.isfile", mockIsFile)

    theProject.projContent = "content"
    theProject.projPath = None
    assert not theTree.writeToCFile()

    theProject.projPath = tmpDir
    assert theTree.writeToCFile()

    pathA = os.path.join("content", "c000000000001.nwd")
    pathB = os.path.join("content", "c000000000002.nwd")
    pathC = os.path.join("content", "b000000000002.nwd")

    assert readFile(os.path.join(tmpDir, nwFiles.TOC_TXT)) == (
        "\n"
        "Table of Contents\n"
        "=================\n"
        "\n"
        "File Name                  Class      Layout    Document Label\n"
        "--------------------------------------------------------------\n"
        f"{pathA}  NOVEL      DOCUMENT  Chapter One\n"
        f"{pathB}  NOVEL      DOCUMENT  Scene One\n"
        f"{pathC}  CHARACTER  NOTE      Jane Doe\n")
Exemplo n.º 11
0
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"
Exemplo n.º 12
0
    def test_readFile(self):
        """
        Test the function readFile
        """
        test_tools_file = os.path.abspath(__file__)
        test_directory = os.path.dirname(test_tools_file)
        non_existing_file = os.path.join(test_directory, "nonExistingFile")

        self.assertIsInstance(tools.readFile(test_tools_file), str)
        self.assertIsNone(tools.readFile(non_existing_file))

        with NamedTemporaryFile('wt') as tmp:
            tmp.write('foo\nbar')
            tmp.flush()
            self.assertIsInstance(tools.readFile(tmp.name), str)
            self.assertEqual(tools.readFile(tmp.name), 'foo\nbar')

        tmp_gz = NamedTemporaryFile().name
        with gzip.open(tmp_gz + '.gz', 'wt') as f:
            f.write('foo\nbar')
            f.flush()
        self.assertIsInstance(tools.readFile(tmp_gz), str)
        self.assertEqual(tools.readFile(tmp_gz), 'foo\nbar')
        os.remove(tmp_gz + '.gz')
Exemplo n.º 13
0
    def test_readFile(self):
        """
        Test the function readFile
        """
        test_tools_file = os.path.abspath(__file__)
        test_directory = os.path.dirname(test_tools_file)
        non_existing_file = os.path.join(test_directory, "nonExistingFile")

        self.assertIsInstance(tools.readFile(test_tools_file), str)
        self.assertIsNone(tools.readFile(non_existing_file))

        with NamedTemporaryFile('wt') as tmp:
            tmp.write('foo\nbar')
            tmp.flush()
            self.assertIsInstance(tools.readFile(tmp.name), str)
            self.assertEqual(tools.readFile(tmp.name), 'foo\nbar')

        tmp_gz = NamedTemporaryFile().name
        with gzip.open(tmp_gz + '.gz', 'wt') as f:
            f.write('foo\nbar')
            f.flush()
        self.assertIsInstance(tools.readFile(tmp_gz), str)
        self.assertEqual(tools.readFile(tmp_gz), 'foo\nbar')
        os.remove(tmp_gz+ '.gz')
Exemplo n.º 14
0
def testCoreProject_Methods(monkeypatch, nwMinimal, dummyGUI, tmpDir):
    """Test other project class methods and functions.
    """
    theProject = NWProject(dummyGUI)
    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, "dummy1")
    assert theProject.setProjectPath(projPath, newProject=True)

    # Make os.mkdir fail
    monkeypatch.setattr("os.mkdir", causeOSError)
    projPath = os.path.join(nwMinimal, "dummy2")
    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
    monkeypatch.setattr("nw.core.project.time", lambda: 1600005600)
    assert theProject.getCurrentEditTime() == 6834
    monkeypatch.undo()

    # 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.projLang is None
    assert theProject.setSpellLang("None")
    assert theProject.projLang is None
    assert theProject.setSpellLang("en_GB")
    assert theProject.projLang == "en_GB"
    assert theProject.projChanged

    # 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].setStatus("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].itemStatus == "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]

    # Check word counts
    theProject.currWCount = 200
    theProject.lastWCount = 100
    assert theProject.getSessionWordCount() == 100

    # Session stats
    monkeypatch.setattr("os.path.isdir", lambda *args, **kwargs: False)
    assert not theProject._appendSessionStats()
    monkeypatch.undo()

    # Block open
    monkeypatch.setattr("builtins.open", causeOSError)
    assert not theProject._appendSessionStats()
    monkeypatch.undo()

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

    theProject.projOpened = 1600002000
    theProject.novelWCount = 200
    theProject.notesWCount = 100

    monkeypatch.setattr("nw.core.project.time", lambda: 1600005600)
    assert theProject._appendSessionStats()
    monkeypatch.undo()

    assert readFile(statsFile) == (
        "# Offset 100\n"
        "# Start Time         End Time                Novel     Notes\n"
        "%s  %s       200       100\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>")
Exemplo n.º 15
0
    opt = input('Which one would you like to run? ')
    print(
        '========================================================================'
    )
    return opt


ap = argparse.ArgumentParser()
ap.add_argument('-p',
                '--path',
                required=True,
                help='path of the instance file')
args = vars(ap.parse_args())
fn = str(args['path'])

S, k, V = readFile(fn)
validateData(S, k, V)

contd = True
while contd:
    opt = printMenu()
    try:
        nopt = int(opt)
        if nopt == 1:
            printSolution('exhaustive search', RechercheExhaustive(k, V, S), V)
        elif nopt == 2:
            printSolution('dynamic programming', AlgoProgDyn(k, V, S), V)
        elif nopt == 3:
            printSolution('greedy', AlgoGlouton(k, V, S), V)
        else:
            print('Please enter a valid option [1-3]')
Exemplo n.º 16
0
                        '--file',
                        default=False,
                        help="file with a puzzle")
    parser.add_argument('-g',
                        '--generate',
                        action='count',
                        default=False,
                        help="generate puzzle board")
    args = parser.parse_args()

    boards = PuzzleBoard()
    if not (args.file or args.generate):
        parser.print_help()
        exit(1)
    elif args.file:
        file = readFile(args.file)
        values = boards.parsePuzzle(file)
        boards.generatePuzzle(values)
    else:
        boards.generatePuzzle(dim=3)

    user, additional = select_algorithm(is_file=args.file)

    save = numpy.copy(boards.pzl)

    if additional != '0' and additional != '1':
        print("[Error] Wrong input")
        exit(1)

    if user == '1' or user == '2' or user == '3':
        heuristic = manhattan_distance if user == '1' else linear_conflict if user == '2' else misplaced
Exemplo n.º 17
0
def testCoreToHtml_Complex(dummyGUI, fncDir):
    """Test the ave method of the ToHtml class.
    """
    theProject = NWProject(dummyGUI)
    theHtml = ToHtml(theProject, dummyGUI)

    # Build Project
    # =============

    docText = [
        "# My Novel\n**By Jane Doh**\n",
        "## Chapter 1\n\nThe text of chapter one.\n",
        "### Scene 1\n\nThe text of scene one.\n",
        "#### A Section\n\nMore text in scene one.\n",
        "## Chapter 2\n\nThe text of chapter two.\n",
        "### Scene 2\n\nThe text of scene two.\n",
        "#### A Section\n\n\tMore text in scene two.\n",
    ]
    resText = [
        "<h1>My Novel</h1>\n<p><strong>By Jane Doh</strong></p>\n",
        "<h2>Chapter 1</h2>\n<p>The text of chapter one.</p>\n",
        "<h3>Scene 1</h3>\n<p>The text of scene one.</p>\n",
        "<h4>A Section</h4>\n<p>More text in scene one.</p>\n",
        "<h2>Chapter 2</h2>\n<p>The text of chapter two.</p>\n",
        "<h3>Scene 2</h3>\n<p>The text of scene two.</p>\n",
        "<h4>A Section</h4>\n<p>\tMore text in scene two.</p>\n",
    ]

    for i in range(len(docText)):
        theHtml.theText = docText[i]
        theHtml.doPreProcessing()
        theHtml.tokenizeText()
        theHtml.doConvert()
        assert theHtml.theResult == resText[i]

    assert theHtml.fullHTML == resText

    theHtml.replaceTabs(nSpaces=2, spaceChar="&nbsp;")
    resText[
        6] = "<h4>A Section</h4>\n<p>&nbsp;&nbsp;More text in scene two.</p>\n"

    # Check File
    # ==========

    theStyle = theHtml.getStyleSheet()
    theStyle.append("article {width: 800px; margin: 40px auto;}")
    htmlDoc = ("<!DOCTYPE html>\n"
               "<html>\n"
               "<head>\n"
               "<meta charset='utf-8'>\n"
               "<title></title>\n"
               "</head>\n"
               "<style>\n"
               "{htmlStyle:s}\n"
               "</style>\n"
               "<body>\n"
               "<article>\n"
               "{bodyText:s}\n"
               "</article>\n"
               "</body>\n"
               "</html>\n").format(htmlStyle="\n".join(theStyle),
                                   bodyText="".join(resText).rstrip())

    saveFile = os.path.join(fncDir, "outFile.htm")
    theHtml.saveHTML5(saveFile)
    assert readFile(saveFile) == htmlDoc
Exemplo n.º 18
0
def testCoreToken_TextOps(monkeypatch, nwMinimal, dummyGUI):
    """Test handling files and text in the Tokenizer class.
    """
    theProject = NWProject(dummyGUI)
    theProject.projTree.setSeed(42)
    theProject.projLang = "en"
    theProject._loadProjectLocalisation()

    theToken = Tokenizer(theProject, dummyGUI)
    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, dummyGUI)
    nDoc.openDocument(sHandle)
    nDoc.saveDocument(docText)
    nDoc.clearDocument()

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

    assert theProject.saveProject()

    # Root heading
    assert theToken.addRootHeading("dummy") is False
    assert theToken.addRootHeading(sHandle) is False
    assert theToken.addRootHeading("7695ce551d265") is True
    assert theToken.theMarkdown[-1] == "# Notes: Plot\n\n"

    # Set text
    assert theToken.setText("dummy") is False
    assert theToken.setText(sHandle) is True
    assert theToken.theText == docText

    with monkeypatch.context() as mp:
        mp.setattr("nw.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.isTitle is False
    assert theToken.isBook is False
    assert theToken.isPage is False
    assert theToken.isPart is False
    assert theToken.isUnNum is False
    assert theToken.isChap is False
    assert theToken.isScene is True
    assert theToken.isNote is False
    assert theToken.isNovel is True

    # 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"
Exemplo n.º 19
0
def testDlgSplit_Main(qtbot, monkeypatch, nwGUI, fncProj, mockRnd):
    """Test the split document tool.
    """
    # Block message box
    monkeypatch.setattr(QMessageBox, "question", lambda *a: QMessageBox.Yes)
    monkeypatch.setattr(QMessageBox, "critical", lambda *a: QMessageBox.Ok)
    monkeypatch.setattr(GuiEditLabel, "getLabel", lambda *a, text:
                        (text, True))

    # Create a new project
    buildTestProject(nwGUI, fncProj)

    # Handles for new objects
    hNovelRoot = "0000000000008"
    hChapterDir = "000000000000d"
    hToSplit = "0000000000010"
    hNewFolder = "0000000000021"
    hPartition = "0000000000022"
    hChapterOne = "0000000000023"
    hSceneOne = "0000000000024"
    hSceneTwo = "0000000000025"
    hSceneThree = "0000000000026"
    hSceneFour = "0000000000027"
    hSceneFive = "0000000000028"

    # Add Project Content
    nwGUI.switchFocus(nwWidget.TREE)
    nwGUI.projView.projTree.clearSelection()
    nwGUI.projView.projTree._getTreeItem(hNovelRoot).setSelected(True)
    nwGUI.projView.projTree.newTreeItem(nwItemType.FILE)

    assert nwGUI.saveProject() is True
    assert nwGUI.closeProject() is True

    tPartition = "# Nantucket"
    tChapterOne = "## Chapter One\n\n% Chapter one comment"
    tSceneOne = "### Scene One\n\nThere once was a man from Nantucket"
    tSceneTwo = "### Scene Two\n\nWho kept all his cash in a bucket."
    tSceneThree = "### Scene Three\n\n\tBut his daughter, named Nan,  \n\tRan away with a man"
    tSceneFour = "### Scene Four\n\nAnd as for the bucket, Nantucket."
    tSceneFive = "#### The End\n\nend"

    tToSplit = (f"{tPartition}\n\n{tChapterOne}\n\n"
                f"{tSceneOne}\n\n{tSceneTwo}\n\n"
                f"{tSceneThree}\n\n{tSceneFour}\n\n"
                f"{tSceneFive}\n\n")

    contentDir = os.path.join(fncProj, "content")
    writeFile(os.path.join(contentDir, hToSplit + ".nwd"), tToSplit)

    assert nwGUI.openProject(fncProj) is True

    # Open the Split tool
    nwGUI.switchFocus(nwWidget.TREE)
    nwGUI.projView.projTree.clearSelection()
    nwGUI.projView.projTree._getTreeItem(hToSplit).setSelected(True)

    monkeypatch.setattr(GuiDocSplit, "exec_", lambda *a: None)
    nwGUI.mainMenu.aSplitDoc.activate(QAction.Trigger)
    qtbot.waitUntil(lambda: getGuiItem("GuiDocSplit") is not None,
                    timeout=1000)

    nwSplit = getGuiItem("GuiDocSplit")
    assert isinstance(nwSplit, GuiDocSplit)
    nwSplit.show()
    qtbot.wait(50)

    # Populate List
    # =============

    nwSplit.listBox.clear()
    assert nwSplit.listBox.count() == 0

    # No item selected
    nwSplit.sourceItem = None
    nwGUI.projView.projTree.clearSelection()
    assert nwSplit._populateList() is False
    assert nwSplit.listBox.count() == 0

    # Non-existing item
    with monkeypatch.context() as mp:
        mp.setattr(NWTree, "__getitem__", lambda *a: None)
        nwSplit.sourceItem = None
        nwGUI.projView.projTree.clearSelection()
        nwGUI.projView.projTree._getTreeItem(hToSplit).setSelected(True)
        assert nwSplit._populateList() is False
        assert nwSplit.listBox.count() == 0

    # Select a non-file
    nwSplit.sourceItem = None
    nwGUI.projView.projTree.clearSelection()
    nwGUI.projView.projTree._getTreeItem(hChapterDir).setSelected(True)
    assert nwSplit._populateList() is False
    assert nwSplit.listBox.count() == 0

    # Error when reading documents
    with monkeypatch.context() as mp:
        mp.setattr(NWDoc, "readDocument", lambda *a: None)
        nwSplit.sourceItem = hToSplit
        assert nwSplit._populateList() is False
        assert nwSplit.listBox.count() == 0

    # Read properly, and check split levels

    # Level 1
    nwSplit.splitLevel.setCurrentIndex(0)
    nwSplit.sourceItem = hToSplit
    assert nwSplit._populateList() is True
    assert nwSplit.listBox.count() == 1

    # Level 2
    nwSplit.splitLevel.setCurrentIndex(1)
    nwSplit.sourceItem = hToSplit
    assert nwSplit._populateList() is True
    assert nwSplit.listBox.count() == 2

    # Level 3
    nwSplit.splitLevel.setCurrentIndex(2)
    nwSplit.sourceItem = hToSplit
    assert nwSplit._populateList() is True
    assert nwSplit.listBox.count() == 6

    # Level 4
    nwSplit.splitLevel.setCurrentIndex(3)
    nwSplit.sourceItem = hToSplit
    assert nwSplit._populateList() is True
    assert nwSplit.listBox.count() == 7

    # Split Document
    # ==============

    # Test a proper split first
    with monkeypatch.context() as mp:
        mp.setattr(GuiDocSplit, "_doClose", lambda *a: None)
        assert nwSplit._doSplit() is True
        assert nwGUI.saveProject()

        assert readFile(os.path.join(
            contentDir, hPartition +
            ".nwd")) == ("%%%%~name: Nantucket\n"
                         "%%%%~path: %s/%s\n"
                         "%%%%~kind: NOVEL/DOCUMENT\n"
                         "%s\n\n") % (hNewFolder, hPartition, tPartition)

        assert readFile(os.path.join(
            contentDir, hChapterOne +
            ".nwd")) == ("%%%%~name: Chapter One\n"
                         "%%%%~path: %s/%s\n"
                         "%%%%~kind: NOVEL/DOCUMENT\n"
                         "%s\n\n") % (hNewFolder, hChapterOne, tChapterOne)

        assert readFile(os.path.join(
            contentDir, hSceneOne +
            ".nwd")) == ("%%%%~name: Scene One\n"
                         "%%%%~path: %s/%s\n"
                         "%%%%~kind: NOVEL/DOCUMENT\n"
                         "%s\n\n") % (hNewFolder, hSceneOne, tSceneOne)

        assert readFile(os.path.join(
            contentDir, hSceneTwo +
            ".nwd")) == ("%%%%~name: Scene Two\n"
                         "%%%%~path: %s/%s\n"
                         "%%%%~kind: NOVEL/DOCUMENT\n"
                         "%s\n\n") % (hNewFolder, hSceneTwo, tSceneTwo)

        assert readFile(os.path.join(
            contentDir, hSceneThree +
            ".nwd")) == ("%%%%~name: Scene Three\n"
                         "%%%%~path: %s/%s\n"
                         "%%%%~kind: NOVEL/DOCUMENT\n"
                         "%s\n\n") % (hNewFolder, hSceneThree, tSceneThree)

        assert readFile(os.path.join(
            contentDir, hSceneFour +
            ".nwd")) == ("%%%%~name: Scene Four\n"
                         "%%%%~path: %s/%s\n"
                         "%%%%~kind: NOVEL/DOCUMENT\n"
                         "%s\n\n") % (hNewFolder, hSceneFour, tSceneFour)

        assert readFile(os.path.join(
            contentDir, hSceneFive +
            ".nwd")) == ("%%%%~name: The End\n"
                         "%%%%~path: %s/%s\n"
                         "%%%%~kind: NOVEL/DOCUMENT\n"
                         "%s\n\n") % (hNewFolder, hSceneFive, tSceneFive)

    # OS error
    with monkeypatch.context() as mp:
        mp.setattr("builtins.open", causeOSError)
        assert nwSplit._doSplit() is False

    # Select to not split
    with monkeypatch.context() as mp:
        mp.setattr(QMessageBox, "question", lambda *a: QMessageBox.No)
        assert nwSplit._doSplit() is False

    # Clear the list
    nwSplit.listBox.clear()
    assert nwSplit._doSplit() is False

    # Can't find sourcv item
    with monkeypatch.context() as mp:
        mp.setattr(NWTree, "__getitem__", lambda *a: None)
        assert nwSplit._doSplit() is False

    # No source item set
    nwSplit.sourceItem = None
    assert nwSplit._doSplit() is False

    # Close
    nwSplit._doClose()
Exemplo n.º 20
0
def testDlgWordList_Dialog(qtbot, monkeypatch, nwGUI, nwMinimal):
    """test the word list editor.
    """
    monkeypatch.setattr(QMessageBox, "question", lambda *a: QMessageBox.Yes)
    monkeypatch.setattr(QMessageBox, "critical", lambda *a: QMessageBox.Yes)
    monkeypatch.setattr(GuiWordList, "exec_", lambda *a: None)
    monkeypatch.setattr(GuiWordList, "result", lambda *a: QDialog.Accepted)
    monkeypatch.setattr(GuiWordList, "accept", lambda *a: None)

    # Open project
    nwGUI.openProject(nwMinimal)
    qtbot.wait(stepDelay)
    dictFile = os.path.join(nwMinimal, "meta", nwFiles.PROJ_DICT)

    # Load the dialog
    nwGUI.mainMenu.aEditWordList.activate(QAction.Trigger)
    qtbot.waitUntil(lambda: getGuiItem("GuiWordList") is not None,
                    timeout=1000)

    wList = getGuiItem("GuiWordList")
    assert isinstance(wList, GuiWordList)
    wList.show()
    qtbot.wait(stepDelay)

    # List should be blank
    assert wList.listBox.count() == 0

    # Add words
    writeFile(
        dictFile,
        (
            "word_a\n"
            "word_c\n"
            "word_g\n"
            "      \n"  # Should be ignored
            "word_f\n"
            "word_b\n"))
    qtbot.wait(stepDelay)
    assert wList._loadWordList()

    # Check that the content was loaded
    assert wList.listBox.item(0).text() == "word_a"
    assert wList.listBox.item(1).text() == "word_b"
    assert wList.listBox.item(2).text() == "word_c"
    assert wList.listBox.item(3).text() == "word_f"
    assert wList.listBox.item(4).text() == "word_g"

    # Add a blank word
    wList.newEntry.setText("   ")
    assert not wList._doAdd()

    # Add an existing word
    wList.newEntry.setText("word_c")
    assert not wList._doAdd()

    # Add a new word
    wList.newEntry.setText("word_d")
    assert wList._doAdd()

    # Check that the content now
    assert wList.listBox.item(0).text() == "word_a"
    assert wList.listBox.item(1).text() == "word_b"
    assert wList.listBox.item(2).text() == "word_c"
    assert wList.listBox.item(3).text() == "word_d"
    assert wList.listBox.item(4).text() == "word_f"
    assert wList.listBox.item(5).text() == "word_g"

    # Delete a word
    wList.newEntry.setText("delete_me")
    assert wList._doAdd()
    assert wList.listBox.item(0).text() == "delete_me"

    delItem = wList.listBox.findItems("delete_me", Qt.MatchExactly)[0]
    assert delItem.text() == "delete_me"
    delItem.setSelected(True)
    wList._doDelete()
    assert wList.listBox.findItems("delete_me", Qt.MatchExactly) == []
    assert wList.listBox.item(0).text() == "word_a"

    # Save files
    assert wList._doSave()
    assert readFile(dictFile) == ("word_a\n"
                                  "word_b\n"
                                  "word_c\n"
                                  "word_d\n"
                                  "word_f\n"
                                  "word_g\n")

    # Save again and make it fail
    monkeypatch.setattr("builtins.open", causeOSError)
    assert not wList._doSave()

    # qtbot.stopForInteraction()
    wList._doClose()
Exemplo n.º 21
0
def makeGnuplotFile(inFile, outFile):
    inLines = [l.replace("\n", "") for l in readFile(inFile)]
    output = "\n".join(createGnuplotFile(inLines))
    print("--------------------------")
    print(output)
    writeFile(outFile, output)
Exemplo n.º 22
0
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)
Exemplo n.º 23
0
def testCoreSpell_Enchant(monkeypatch, tmpDir):
    """Test the pyenchant spell checker
    """
    wList = os.path.join(tmpDir, "wordlist.txt")
    writeFile(wList, "a_word\nb_word\nc_word\n")

    # Block the enchant package (and trigger the default class)
    with monkeypatch.context() as mp:
        mp.setitem(sys.modules, "enchant", None)
        spChk = NWSpellEnchant()

        spChk.setLanguage("en", wList)
        assert spChk.setLanguage("", "") is None
        assert spChk.checkWord("") is True
        assert spChk.suggestWords("") == []
        assert spChk.listDictionaries() == []
        assert spChk.describeDict() == ("", "")

    # Break the enchant package, and check error handling
    spChk = NWSpellEnchant()
    spChk.theDict = None
    assert spChk.checkWord("word") is True
    assert spChk.suggestWords("word") == []
    assert spChk.addWord("word") is False

    # Load the proper enchant package (twice)
    spChk = NWSpellEnchant()
    spChk.setLanguage("en", wList)
    spChk.setLanguage("en", wList)

    # Add a word to the user's dictionary
    assert spChk._readProjectDictionary("stuff") is False
    with monkeypatch.context() as mp:
        mp.setattr("builtins.open", causeOSError)
        assert spChk._readProjectDictionary(wList) is False

    assert spChk._readProjectDictionary(None) is False
    assert spChk._readProjectDictionary(wList) is True
    assert spChk._projectDict == wList

    # Cannot write to file
    with monkeypatch.context() as mp:
        mp.setattr("builtins.open", causeOSError)
        assert spChk.addWord("d_word") is False

    assert readFile(wList) == "a_word\nb_word\nc_word\n"
    assert spChk.addWord("d_word") is True
    assert readFile(wList) == "a_word\nb_word\nc_word\nd_word\n"
    assert spChk.addWord("d_word") is False

    # Check words
    assert spChk.checkWord("a_word") is True
    assert spChk.checkWord("b_word") is True
    assert spChk.checkWord("c_word") is True
    assert spChk.checkWord("d_word") is True
    assert spChk.checkWord("e_word") is False

    spChk.addWord("d_word")
    assert spChk.checkWord("d_word") is True

    wSuggest = spChk.suggestWords("wrod")
    assert len(wSuggest) > 0
    assert "word" in wSuggest

    dList = spChk.listDictionaries()
    assert len(dList) > 0

    aTag, aName = spChk.describeDict()
    assert aTag == "en"
    assert aName != ""
Exemplo n.º 24
0
def findStrFromBox2(anno, box, filename, pheight, verbose=True):
    '''Locate and extract strings from a page layout obj

    Extract text using pdftotext
    '''

    texts = u''
    num = 0
    # pdftotext requires int coordinates, scale default dpi of
    # pdftotext (72) to 720, and multiply coordinates by 10.
    coord2str = lambda x: int(round(10. * x))

    #----------------Loop through annos----------------
    for ii, hii in enumerate(anno):

        #----------Create a dummy LTTextLine obj----------
        hiibox = hii['rect']
        dummy = LTTextLine(hiibox)
        dummy.set_bbox(hiibox)  #Needs this step

        if box.is_hoverlap(dummy) and box.is_voverlap(dummy):
            textii = []
            num += 1

            lines = sortY(box._objs)

            #----------------Loop through lines----------------
            for lineii in lines:
                if type(lineii)!=LTTextLine and\
                        type(lineii)!=LTTextLineHorizontal:
                    continue
                if lineii.is_hoverlap(dummy) and\
                        lineii.is_voverlap(dummy):

                    #------Call pdftotext and same to a temp file------
                    # NOTE: pdftotext coordinate has origin at top-left.
                    # Coordinates from Mendeley has origin at bottom-left.
                    args=['pdftotext','-f',hii['page'],'-l',hii['page'],'-r',720,\
                            '-x',coord2str(hiibox[0]),'-y',coord2str(pheight-hiibox[3]),\
                            '-W',coord2str(hiibox[2]-hiibox[0]),'-H',coord2str(hiibox[3]-hiibox[1]),\
                            os.path.abspath(filename),'tmp.txt']
                    args = map(str, args)

                    pp = Popen(args)
                    while pp.poll() != 0:
                        time.sleep(0.01)

                    tii = tools.readFile('tmp.txt', False)
                    textii.append(tii)

                    # break to avoid double sampling. Lines from lineii may
                    # overlap, and may fetch a highlight twice if not break.
                    break

            #----------------Concatenate texts----------------
            textii = u''.join(textii).strip(' ')

            textii = textii.strip('\n')
            textii = textii.replace('\n', ' ')

            #---------------Join with next line---------------
            if len(texts) > 1 and texts[-1] == '-':
                texts = texts[:-1]
                joiner = u''
            else:
                joiner = u' '

            #---------------Jump---------------
            linegap, chargap = measureGap(lines)
            textii = textii.strip()
            if ii == 0 or len(texts) == 0:
                texts += joiner + textii
                lastbox = hiibox
            else:
                #lastbox=anno[ii-1]['rect']
                if checkJump(lastbox, hiibox, lineii, linegap, chargap):
                    textii = u' ...... ' + textii
                    texts += joiner + textii
                else:
                    texts += joiner + textii

            lastbox = hiibox

    texts = texts.strip()

    #------------------Do some fixes------------------
    if len(texts) > 0:
        texts = wordfix.fixWord(texts)

    return texts, num
Exemplo n.º 25
0
def testDlgMerge_Main(qtbot, monkeypatch, nwGUI, fncProj):
    """Test the merge documents tool.
    """
    # Block message box
    monkeypatch.setattr(QMessageBox, "question", lambda *a: QMessageBox.Yes)
    monkeypatch.setattr(QMessageBox, "critical", lambda *a: QMessageBox.Ok)

    # Create a new project
    nwGUI.theProject.projTree.setSeed(42)
    assert nwGUI.newProject({"projPath": fncProj})

    # Handles for new objects
    hChapterDir = "31489056e0916"
    hChapterOne = "98010bd9270f9"
    hSceneOne   = "0e17daca5f3e1"
    hSceneTwo   = "1a6562590ef19"
    hSceneThree = "031b4af5197ec"
    hSceneFour  = "41cfc0d1f2d12"
    hMergedDoc  = "2858dcd1057d3"

    # Add Project Content
    monkeypatch.setattr(GuiItemEditor, "exec_", lambda *a: QDialog.Accepted)
    nwGUI.switchFocus(nwWidget.TREE)
    nwGUI.treeView.clearSelection()
    nwGUI.treeView._getTreeItem(hChapterDir).setSelected(True)
    nwGUI.treeView.newTreeItem(nwItemType.FILE, None)
    nwGUI.treeView.newTreeItem(nwItemType.FILE, None)
    nwGUI.treeView.newTreeItem(nwItemType.FILE, None)

    assert nwGUI.saveProject() is True
    assert nwGUI.closeProject() is True

    tChapterOne = "## Chapter One\n\n% Chapter one comment\n"
    tSceneOne   = "### Scene One\n\nThere once was a man from Nantucket"
    tSceneTwo   = "### Scene Two\n\nWho kept all his cash in a bucket."
    tSceneThree = "### Scene Three\n\n\tBut his daughter, named Nan,  \n\tRan away with a man"
    tSceneFour  = "### Scene Four\n\nAnd as for the bucket, Nantucket."

    contentDir = os.path.join(fncProj, "content")
    writeFile(os.path.join(contentDir, hChapterOne+".nwd"), tChapterOne)
    writeFile(os.path.join(contentDir, hSceneOne+".nwd"), tSceneOne)
    writeFile(os.path.join(contentDir, hSceneTwo+".nwd"), tSceneTwo)
    writeFile(os.path.join(contentDir, hSceneThree+".nwd"), tSceneThree)
    writeFile(os.path.join(contentDir, hSceneFour+".nwd"), tSceneFour)

    assert nwGUI.openProject(fncProj) is True

    # Open the Merge tool
    nwGUI.switchFocus(nwWidget.TREE)
    nwGUI.treeView.clearSelection()
    nwGUI.treeView._getTreeItem(hChapterDir).setSelected(True)

    monkeypatch.setattr(GuiDocMerge, "exec_", lambda *a: None)
    nwGUI.mainMenu.aMergeDocs.activate(QAction.Trigger)
    qtbot.waitUntil(lambda: getGuiItem("GuiDocMerge") is not None, timeout=1000)

    nwMerge = getGuiItem("GuiDocMerge")
    assert isinstance(nwMerge, GuiDocMerge)
    nwMerge.show()
    qtbot.wait(50)

    # Populate List
    # =============

    nwMerge.listBox.clear()
    assert nwMerge.listBox.count() == 0

    # No item selected
    nwGUI.treeView.clearSelection()
    assert nwMerge._populateList() is False
    assert nwMerge.listBox.count() == 0

    # Non-existing item
    with monkeypatch.context() as mp:
        mp.setattr(NWTree, "__getitem__", lambda *a: None)
        nwGUI.treeView.clearSelection()
        nwGUI.treeView._getTreeItem(hChapterDir).setSelected(True)
        assert nwMerge._populateList() is False
        assert nwMerge.listBox.count() == 0

    # Select a non-folder
    nwGUI.treeView.clearSelection()
    nwGUI.treeView._getTreeItem(hChapterOne).setSelected(True)
    assert nwMerge._populateList() is False
    assert nwMerge.listBox.count() == 0

    # Select the chapter folder
    nwGUI.treeView.clearSelection()
    nwGUI.treeView._getTreeItem(hChapterDir).setSelected(True)
    assert nwMerge._populateList() is True
    assert nwMerge.listBox.count() == 5

    # Merge Documents
    # ===============

    # First, a successful merge
    with monkeypatch.context() as mp:
        mp.setattr(GuiDocMerge, "_doClose", lambda *a: None)
        assert nwMerge._doMerge() is True
        assert nwGUI.saveProject() is True
        mergedFile = os.path.join(contentDir, hMergedDoc+".nwd")
        assert os.path.isfile(mergedFile)
        assert readFile(mergedFile) == (
            "%%%%~name: New Chapter\n"
            "%%%%~path: 73475cb40a568/2858dcd1057d3\n"
            "%%%%~kind: NOVEL/DOCUMENT\n"
            "%s\n\n"
            "%s\n\n"
            "%s\n\n"
            "%s\n\n"
            "%s\n\n"
        ) % (
            tChapterOne.strip(),
            tSceneOne.strip(),
            tSceneTwo.strip(),
            tSceneThree.strip(),
            tSceneFour.strip(),
        )

    # OS error
    with monkeypatch.context() as mp:
        mp.setattr("builtins.open", causeOSError)
        assert nwMerge._doMerge() is False

    # Can't find the source item
    with monkeypatch.context() as mp:
        mp.setattr(NWTree, "__getitem__", lambda *a: None)
        assert nwMerge._doMerge() is False

    # No source handle set
    nwMerge.sourceItem = None
    assert nwMerge._doMerge() is False

    # No documents to merge
    nwMerge.listBox.clear()
    assert nwMerge._doMerge() is False

    # Close up
    nwMerge._doClose()
Exemplo n.º 26
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()
Exemplo n.º 27
0
def testDlgSplit_Main(qtbot, monkeypatch, nwGUI, fncProj):
    """Test the split document tool.
    """
    # Block message box
    monkeypatch.setattr(QMessageBox, "question", lambda *a: QMessageBox.Yes)
    monkeypatch.setattr(QMessageBox, "critical", lambda *a: QMessageBox.Ok)

    # Create a new project
    nwGUI.theProject.projTree.setSeed(42)
    assert nwGUI.newProject({"projPath": fncProj}) is True

    # Handles for new objects
    hNovelRoot  = "73475cb40a568"
    hChapterDir = "31489056e0916"
    hToSplit    = "1a6562590ef19"
    hPartition  = "41cfc0d1f2d12"
    hChapterOne = "2858dcd1057d3"
    hSceneOne   = "2fca346db6561"
    hSceneTwo   = "02d20bbd7e394"
    hSceneThree = "7688b6ef52555"
    hSceneFour  = "c837649cce43f"
    hSceneFive  = "6208ef0f7750c"

    # Add Project Content
    monkeypatch.setattr(GuiItemEditor, "exec_", lambda *a: QDialog.Accepted)
    nwGUI.switchFocus(nwWidget.TREE)
    nwGUI.treeView.clearSelection()
    nwGUI.treeView._getTreeItem(hNovelRoot).setSelected(True)
    nwGUI.treeView.newTreeItem(nwItemType.FILE, None)

    assert nwGUI.saveProject() is True
    assert nwGUI.closeProject() is True

    tPartition  = "# Nantucket"
    tChapterOne = "## Chapter One\n\n% Chapter one comment"
    tSceneOne   = "### Scene One\n\nThere once was a man from Nantucket"
    tSceneTwo   = "### Scene Two\n\nWho kept all his cash in a bucket."
    tSceneThree = "### Scene Three\n\n\tBut his daughter, named Nan,  \n\tRan away with a man"
    tSceneFour  = "### Scene Four\n\nAnd as for the bucket, Nantucket."
    tSceneFive  = "#### The End\n\nend"

    tToSplit = (
        f"{tPartition}\n\n{tChapterOne}\n\n"
        f"{tSceneOne}\n\n{tSceneTwo}\n\n"
        f"{tSceneThree}\n\n{tSceneFour}\n\n"
        f"{tSceneFive}\n\n"
    )

    contentDir = os.path.join(fncProj, "content")
    writeFile(os.path.join(contentDir, hToSplit+".nwd"), tToSplit)

    assert nwGUI.openProject(fncProj) is True

    # Open the Split tool
    nwGUI.switchFocus(nwWidget.TREE)
    nwGUI.treeView.clearSelection()
    nwGUI.treeView._getTreeItem(hToSplit).setSelected(True)

    monkeypatch.setattr(GuiDocSplit, "exec_", lambda *a: None)
    nwGUI.mainMenu.aSplitDoc.activate(QAction.Trigger)
    qtbot.waitUntil(lambda: getGuiItem("GuiDocSplit") is not None, timeout=1000)

    nwSplit = getGuiItem("GuiDocSplit")
    assert isinstance(nwSplit, GuiDocSplit)
    nwSplit.show()
    qtbot.wait(50)

    # Populate List
    # =============

    nwSplit.listBox.clear()
    assert nwSplit.listBox.count() == 0

    # No item selected
    nwSplit.sourceItem = None
    nwGUI.treeView.clearSelection()
    assert nwSplit._populateList() is False
    assert nwSplit.listBox.count() == 0

    # Non-existing item
    with monkeypatch.context() as mp:
        mp.setattr(NWTree, "__getitem__", lambda *a: None)
        nwSplit.sourceItem = None
        nwGUI.treeView.clearSelection()
        nwGUI.treeView._getTreeItem(hToSplit).setSelected(True)
        assert nwSplit._populateList() is False
        assert nwSplit.listBox.count() == 0

    # Select a non-file
    nwSplit.sourceItem = None
    nwGUI.treeView.clearSelection()
    nwGUI.treeView._getTreeItem(hChapterDir).setSelected(True)
    assert nwSplit._populateList() is False
    assert nwSplit.listBox.count() == 0

    # Error when reading documents
    with monkeypatch.context() as mp:
        mp.setattr(NWDoc, "readDocument", lambda *a: None)
        nwSplit.sourceItem = hToSplit
        assert nwSplit._populateList() is False
        assert nwSplit.listBox.count() == 0

    # Read properly, and check split levels

    # Level 1
    nwSplit.splitLevel.setCurrentIndex(0)
    nwSplit.sourceItem = hToSplit
    assert nwSplit._populateList() is True
    assert nwSplit.listBox.count() == 1

    # Level 2
    nwSplit.splitLevel.setCurrentIndex(1)
    nwSplit.sourceItem = hToSplit
    assert nwSplit._populateList() is True
    assert nwSplit.listBox.count() == 2

    # Level 3
    nwSplit.splitLevel.setCurrentIndex(2)
    nwSplit.sourceItem = hToSplit
    assert nwSplit._populateList() is True
    assert nwSplit.listBox.count() == 6

    # Level 4
    nwSplit.splitLevel.setCurrentIndex(3)
    nwSplit.sourceItem = hToSplit
    assert nwSplit._populateList() is True
    assert nwSplit.listBox.count() == 7

    # Split Document
    # ==============

    # Test a proper split first
    with monkeypatch.context() as mp:
        mp.setattr(GuiDocSplit, "_doClose", lambda *a: None)
        assert nwSplit._doSplit() is True
        assert nwGUI.saveProject()

        assert readFile(os.path.join(contentDir, hPartition+".nwd")) == (
            "%%%%~name: Nantucket\n"
            "%%%%~path: 031b4af5197ec/%s\n"
            "%%%%~kind: NOVEL/DOCUMENT\n"
            "%s\n\n"
        ) % (hPartition, tPartition)

        assert readFile(os.path.join(contentDir, hChapterOne+".nwd")) == (
            "%%%%~name: Chapter One\n"
            "%%%%~path: 031b4af5197ec/%s\n"
            "%%%%~kind: NOVEL/DOCUMENT\n"
            "%s\n\n"
        ) % (hChapterOne, tChapterOne)

        assert readFile(os.path.join(contentDir, hSceneOne+".nwd")) == (
            "%%%%~name: Scene One\n"
            "%%%%~path: 031b4af5197ec/%s\n"
            "%%%%~kind: NOVEL/DOCUMENT\n"
            "%s\n\n"
        ) % (hSceneOne, tSceneOne)

        assert readFile(os.path.join(contentDir, hSceneTwo+".nwd")) == (
            "%%%%~name: Scene Two\n"
            "%%%%~path: 031b4af5197ec/%s\n"
            "%%%%~kind: NOVEL/DOCUMENT\n"
            "%s\n\n"
        ) % (hSceneTwo, tSceneTwo)

        assert readFile(os.path.join(contentDir, hSceneThree+".nwd")) == (
            "%%%%~name: Scene Three\n"
            "%%%%~path: 031b4af5197ec/%s\n"
            "%%%%~kind: NOVEL/DOCUMENT\n"
            "%s\n\n"
        ) % (hSceneThree, tSceneThree)

        assert readFile(os.path.join(contentDir, hSceneFour+".nwd")) == (
            "%%%%~name: Scene Four\n"
            "%%%%~path: 031b4af5197ec/%s\n"
            "%%%%~kind: NOVEL/DOCUMENT\n"
            "%s\n\n"
        ) % (hSceneFour, tSceneFour)

        assert readFile(os.path.join(contentDir, hSceneFive+".nwd")) == (
            "%%%%~name: The End\n"
            "%%%%~path: 031b4af5197ec/%s\n"
            "%%%%~kind: NOVEL/DOCUMENT\n"
            "%s\n\n"
        ) % (hSceneFive, tSceneFive)

    # OS error
    with monkeypatch.context() as mp:
        mp.setattr("builtins.open", causeOSError)
        assert nwSplit._doSplit() is False

    # Select to not split
    with monkeypatch.context() as mp:
        mp.setattr(QMessageBox, "question", lambda *a: QMessageBox.No)
        assert nwSplit._doSplit() is False

    # Block folder creation by returning that the folder has a depth
    # of 50 items in the tree
    with monkeypatch.context() as mp:
        mp.setattr(NWTree, "getItemPath", lambda *a: [""]*50)
        assert nwSplit._doSplit() is False

    # Clear the list
    nwSplit.listBox.clear()
    assert nwSplit._doSplit() is False

    # Can't find sourcv item
    with monkeypatch.context() as mp:
        mp.setattr(NWTree, "__getitem__", lambda *a: None)
        assert nwSplit._doSplit() is False

    # No source item set
    nwSplit.sourceItem = None
    assert nwSplit._doSplit() is False

    # Close
    nwSplit._doClose()
Exemplo n.º 28
0
def testDlgMerge_Main(qtbot, monkeypatch, nwGUI, fncProj, mockRnd):
    """Test the merge documents tool.
    """
    # Block message box
    monkeypatch.setattr(QMessageBox, "question", lambda *a: QMessageBox.Yes)
    monkeypatch.setattr(QMessageBox, "critical", lambda *a: QMessageBox.Ok)
    monkeypatch.setattr(GuiEditLabel, "getLabel", lambda *a, text: (text, True))

    # Create a new project
    buildTestProject(nwGUI, fncProj)

    # Handles for new objects
    hNovelRoot  = "0000000000008"
    hChapterDir = "000000000000d"
    hChapterOne = "000000000000e"
    hSceneOne   = "000000000000f"
    hSceneTwo   = "0000000000010"
    hSceneThree = "0000000000011"
    hSceneFour  = "0000000000012"
    hMergedDoc  = "0000000000023"

    # Add Project Content
    nwGUI.switchFocus(nwWidget.TREE)
    nwGUI.projView.projTree.clearSelection()
    nwGUI.projView.projTree._getTreeItem(hChapterDir).setSelected(True)
    nwGUI.projView.projTree.newTreeItem(nwItemType.FILE)
    nwGUI.projView.projTree.newTreeItem(nwItemType.FILE)
    nwGUI.projView.projTree.newTreeItem(nwItemType.FILE)

    assert nwGUI.saveProject() is True
    assert nwGUI.closeProject() is True

    tChapterOne = "## Chapter One\n\n% Chapter one comment\n"
    tSceneOne   = "### Scene One\n\nThere once was a man from Nantucket"
    tSceneTwo   = "### Scene Two\n\nWho kept all his cash in a bucket."
    tSceneThree = "### Scene Three\n\n\tBut his daughter, named Nan,  \n\tRan away with a man"
    tSceneFour  = "### Scene Four\n\nAnd as for the bucket, Nantucket."

    contentDir = os.path.join(fncProj, "content")
    writeFile(os.path.join(contentDir, hChapterOne+".nwd"), tChapterOne)
    writeFile(os.path.join(contentDir, hSceneOne+".nwd"), tSceneOne)
    writeFile(os.path.join(contentDir, hSceneTwo+".nwd"), tSceneTwo)
    writeFile(os.path.join(contentDir, hSceneThree+".nwd"), tSceneThree)
    writeFile(os.path.join(contentDir, hSceneFour+".nwd"), tSceneFour)

    assert nwGUI.openProject(fncProj) is True

    # Open the Merge tool
    nwGUI.switchFocus(nwWidget.TREE)
    nwGUI.projView.projTree.clearSelection()
    nwGUI.projView.projTree._getTreeItem(hChapterDir).setSelected(True)

    monkeypatch.setattr(GuiDocMerge, "exec_", lambda *a: None)
    nwGUI.mainMenu.aMergeDocs.activate(QAction.Trigger)
    qtbot.waitUntil(lambda: getGuiItem("GuiDocMerge") is not None, timeout=1000)

    nwMerge = getGuiItem("GuiDocMerge")
    assert isinstance(nwMerge, GuiDocMerge)
    nwMerge.show()
    qtbot.wait(50)

    # Populate List
    # =============

    nwMerge.listBox.clear()
    assert nwMerge.listBox.count() == 0

    # No item selected
    nwGUI.projView.projTree.clearSelection()
    assert nwMerge._populateList() is False
    assert nwMerge.listBox.count() == 0

    # Non-existing item
    with monkeypatch.context() as mp:
        mp.setattr(NWTree, "__getitem__", lambda *a: None)
        nwGUI.projView.projTree.clearSelection()
        nwGUI.projView.projTree._getTreeItem(hChapterDir).setSelected(True)
        assert nwMerge._populateList() is False
        assert nwMerge.listBox.count() == 0

    # Select a non-folder
    nwGUI.projView.projTree.clearSelection()
    nwGUI.projView.projTree._getTreeItem(hChapterOne).setSelected(True)
    assert nwMerge._populateList() is False
    assert nwMerge.listBox.count() == 0

    # Select the chapter folder
    nwGUI.projView.projTree.clearSelection()
    nwGUI.projView.projTree._getTreeItem(hChapterDir).setSelected(True)
    assert nwMerge._populateList() is True
    assert nwMerge.listBox.count() == 5

    # Merge Documents
    # ===============

    # First, a successful merge
    with monkeypatch.context() as mp:
        mp.setattr(GuiDocMerge, "_doClose", lambda *a: None)
        assert nwMerge._doMerge() is True
        assert nwGUI.saveProject() is True
        mergedFile = os.path.join(contentDir, hMergedDoc+".nwd")
        assert os.path.isfile(mergedFile)
        assert readFile(mergedFile) == (
            "%%%%~name: New Chapter\n"
            "%%%%~path: %s/%s\n"
            "%%%%~kind: NOVEL/DOCUMENT\n"
            "%s\n\n"
            "%s\n\n"
            "%s\n\n"
            "%s\n\n"
            "%s\n\n"
        ) % (
            hNovelRoot,
            hMergedDoc,
            tChapterOne.strip(),
            tSceneOne.strip(),
            tSceneTwo.strip(),
            tSceneThree.strip(),
            tSceneFour.strip(),
        )

    # OS error
    with monkeypatch.context() as mp:
        mp.setattr("builtins.open", causeOSError)
        assert nwMerge._doMerge() is False

    # Can't find the source item
    with monkeypatch.context() as mp:
        mp.setattr(NWTree, "__getitem__", lambda *a: None)
        assert nwMerge._doMerge() is False

    # No source handle set
    nwMerge.sourceItem = None
    assert nwMerge._doMerge() is False

    # No documents to merge
    nwMerge.listBox.clear()
    assert nwMerge._doMerge() is False

    # Close up
    nwMerge._doClose()