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)
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
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)
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
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"
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
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)
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)
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")
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"
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')
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')
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>")
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]')
'--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
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=" ") resText[ 6] = "<h4>A Section</h4>\n<p> 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
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"
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()
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()
def makeGnuplotFile(inFile, outFile): inLines = [l.replace("\n", "") for l in readFile(inFile)] output = "\n".join(createGnuplotFile(inLines)) print("--------------------------") print(output) writeFile(outFile, output)
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)
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 != ""
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
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()
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 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()
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()