From 969823b8de20c541917befd29d477b2640628d78 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Wed, 28 Apr 2021 23:44:16 -0700 Subject: [PATCH 01/12] gitutils: add diffStrings, diffFiles, and use it in testament to compare expected vs gotten --- lib/std/private/gitutils.nim | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/lib/std/private/gitutils.nim b/lib/std/private/gitutils.nim index bf5e7cb1ff453..99527a9cbe805 100644 --- a/lib/std/private/gitutils.nim +++ b/lib/std/private/gitutils.nim @@ -4,7 +4,7 @@ internal API for now, API subject to change # xxx move other git utilities here; candidate for stdlib. -import std/[os, osproc, strutils] +import std/[os, osproc, strutils, tempfiles] const commitHead* = "HEAD" @@ -38,3 +38,26 @@ proc isGitRepo*(dir: string): bool = # usually a series of ../), so we know that it's safe to unconditionally # remove trailing whitespaces from the result. result = status == 0 and output.strip() == "" + + +proc diffStrings*(a, b: string): string = + runnableExamples: + let a = "ok1\nok2\nok3" + let b = "ok1\nok2 alt\nok3" + let c = diffStrings(a, b) + echo c + + template tmpFileImpl(prefix, str): auto = + # pending + let (fd, path) = createTempFile(prefix, "") + defer: + close fd + removeFile(path) + writeFile(path, str) + (fd, path) + let (fda, patha) = tmpFileImpl("diffStrings_a", a) + let (fdb, pathb) = tmpFileImpl("diffStrings_b", b) + # could be customized, e.g. non-git diff with `diff -uNdr`, or with git diff options. + var status = 0 + (result, status) = execCmdEx("git diff --no-index $1 $2" % [patha.quoteShell, pathb.quoteShell]) + echo status From d75ebeadce7301dd331ee65dea6adbe86059ea30 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Thu, 29 Apr 2021 00:33:01 -0700 Subject: [PATCH 02/12] _ --- lib/std/private/gitutils.nim | 7 +++---- lib/std/tempfiles.nim | 20 ++++++++++++++------ 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/lib/std/private/gitutils.nim b/lib/std/private/gitutils.nim index 99527a9cbe805..2f3c0a095c2aa 100644 --- a/lib/std/private/gitutils.nim +++ b/lib/std/private/gitutils.nim @@ -39,7 +39,6 @@ proc isGitRepo*(dir: string): bool = # remove trailing whitespaces from the result. result = status == 0 and output.strip() == "" - proc diffStrings*(a, b: string): string = runnableExamples: let a = "ok1\nok2\nok3" @@ -48,10 +47,10 @@ proc diffStrings*(a, b: string): string = echo c template tmpFileImpl(prefix, str): auto = - # pending - let (fd, path) = createTempFile(prefix, "") + # pending https://github.com/nim-lang/Nim/pull/17889 + # let (fd, path) = createTempFile(prefix, "") + let path = genTempPath(prefix, "") defer: - close fd removeFile(path) writeFile(path, str) (fd, path) diff --git a/lib/std/tempfiles.nim b/lib/std/tempfiles.nim index 2a6fe7d833cd4..1b45f372d8f24 100644 --- a/lib/std/tempfiles.nim +++ b/lib/std/tempfiles.nim @@ -90,13 +90,21 @@ template randomPathName(length: Natural): string = res[i] = state.sample(letters) res +proc genTempPath*(prefix, suffix: string, dir = ""): string = + ## Generates a path name in `dir`. + ## + ## If `dir` is empty, (`getTempDir `_) will be used. + ## The path begins with `prefix` and ends with `suffix`. + var dir = dir + if dir.len == 0: + dir = getTempDir() + result = dir / (prefix & randomPathName(nimTempPathLength) & suffix) + proc createTempFile*(prefix, suffix: string, dir = ""): tuple[fd: File, path: string] = - ## `createTempFile` creates a new temporary file in the directory `dir`. + ## Creates a new temporary file in the directory `dir`. ## - ## If `dir` is the empty string, the default directory for temporary files - ## (`getTempDir `_) will be used. - ## The temporary file name begins with `prefix` and ends with `suffix`. - ## `createTempFile` returns a file handle to an open file and the path of that file. + ## This generates a path name using `genTempPath(prefix, suffix, dir)` and + ## returns a file handle to an open file and the path of that file. ## ## If failing to create a temporary file, `IOError` will be raised. ## @@ -108,7 +116,7 @@ proc createTempFile*(prefix, suffix: string, dir = ""): tuple[fd: File, path: st createDir(dir) for i in 0 ..< maxRetry: - result.path = dir / (prefix & randomPathName(nimTempPathLength) & suffix) + result.path = createTempPath(prefix, suffix, dir) try: result.fd = safeOpen(result.path) except OSError: From 6525d9d592e9b0bab3c7383630dd0c073b329f0e Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Thu, 29 Apr 2021 01:09:15 -0700 Subject: [PATCH 03/12] _ --- lib/std/private/gitutils.nim | 13 ++++++++----- lib/std/tempfiles.nim | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/lib/std/private/gitutils.nim b/lib/std/private/gitutils.nim index 2f3c0a095c2aa..db0c607255169 100644 --- a/lib/std/private/gitutils.nim +++ b/lib/std/private/gitutils.nim @@ -45,17 +45,20 @@ proc diffStrings*(a, b: string): string = let b = "ok1\nok2 alt\nok3" let c = diffStrings(a, b) echo c + let c2 = diffStrings(a, a) + echo c2 template tmpFileImpl(prefix, str): auto = # pending https://github.com/nim-lang/Nim/pull/17889 # let (fd, path) = createTempFile(prefix, "") let path = genTempPath(prefix, "") - defer: - removeFile(path) writeFile(path, str) - (fd, path) - let (fda, patha) = tmpFileImpl("diffStrings_a", a) - let (fdb, pathb) = tmpFileImpl("diffStrings_b", b) + path + let patha = tmpFileImpl("diffStrings_a_", a) + let pathb = tmpFileImpl("diffStrings_b_", b) + defer: + removeFile(patha) + removeFile(pathb) # could be customized, e.g. non-git diff with `diff -uNdr`, or with git diff options. var status = 0 (result, status) = execCmdEx("git diff --no-index $1 $2" % [patha.quoteShell, pathb.quoteShell]) diff --git a/lib/std/tempfiles.nim b/lib/std/tempfiles.nim index 1b45f372d8f24..c9fff0e7f8502 100644 --- a/lib/std/tempfiles.nim +++ b/lib/std/tempfiles.nim @@ -116,7 +116,7 @@ proc createTempFile*(prefix, suffix: string, dir = ""): tuple[fd: File, path: st createDir(dir) for i in 0 ..< maxRetry: - result.path = createTempPath(prefix, suffix, dir) + result.path = genTempPath(prefix, suffix, dir) try: result.fd = safeOpen(result.path) except OSError: From a192bbfd7ef1c4e8fb9dfbcc5da135b4e0907526 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Thu, 29 Apr 2021 02:17:28 -0700 Subject: [PATCH 04/12] fixup --- lib/std/private/gitutils.nim | 32 +++++++++++++++++++++----------- nimdoc/rsttester.nim | 3 ++- nimdoc/tester.nim | 3 ++- nimpretty/tester.nim | 5 +++-- testament/categories.nim | 4 ++-- testament/testament.nim | 3 ++- 6 files changed, 32 insertions(+), 18 deletions(-) diff --git a/lib/std/private/gitutils.nim b/lib/std/private/gitutils.nim index db0c607255169..16eaf3580fcfe 100644 --- a/lib/std/private/gitutils.nim +++ b/lib/std/private/gitutils.nim @@ -39,14 +39,27 @@ proc isGitRepo*(dir: string): bool = # remove trailing whitespaces from the result. result = status == 0 and output.strip() == "" -proc diffStrings*(a, b: string): string = +proc diffFiles*(path1, path2: string): tuple[output: string, same: bool] = + # could be customized, e.g. non-git diff with `diff -uNdr`, or with git diff options (e.g. --color-moved, --word-diff). + # in general, git diff has more options. + var status = 0 + (result.output, status) = execCmdEx("git diff --no-index $1 $2" % [path1.quoteShell, path2.quoteShell]) + doAssert (status == 0) or (status == 1) + result.same = status == 0 + +proc diffStrings*(a, b: string): tuple[output: string, same: bool] = runnableExamples: - let a = "ok1\nok2\nok3" - let b = "ok1\nok2 alt\nok3" - let c = diffStrings(a, b) - echo c - let c2 = diffStrings(a, a) - echo c2 + let a = "ok1\nok2\nok3\n" + let b = "ok1\nok2 alt\nok3\nok4\n" + let (c, same) = diffStrings(a, b) + doAssert not same + let (c2, same2) = diffStrings(a, a) + doAssert same2 + + runnableExamples("-r:off"): + let a = "ok1\nok2\nok3\n" + let b = "ok1\nok2 alt\nok3\nok4\n" + echo diffStrings(a, b).output template tmpFileImpl(prefix, str): auto = # pending https://github.com/nim-lang/Nim/pull/17889 @@ -59,7 +72,4 @@ proc diffStrings*(a, b: string): string = defer: removeFile(patha) removeFile(pathb) - # could be customized, e.g. non-git diff with `diff -uNdr`, or with git diff options. - var status = 0 - (result, status) = execCmdEx("git diff --no-index $1 $2" % [patha.quoteShell, pathb.quoteShell]) - echo status + result = diffFiles(patha, pathb) diff --git a/nimdoc/rsttester.nim b/nimdoc/rsttester.nim index 6d41ffb86b7a0..daca3dfc76804 100644 --- a/nimdoc/rsttester.nim +++ b/nimdoc/rsttester.nim @@ -1,4 +1,5 @@ import os, strutils +from std/private/gitutils import diffFiles const baseDir = "nimdoc/rst2html" @@ -19,7 +20,7 @@ proc testRst2Html(fixup = false) = exec("$1 rst2html $2" % [nimExe, sourceFile]) let producedHtml = expectedHtml.replace('\\', '/').replace("/expected/", "/source/htmldocs/") if readFile(expectedHtml) != readFile(producedHtml): - discard execShellCmd("diff -uNdr " & expectedHtml & " " & producedHtml) + echo diffFiles(expectedHtml, producedHtml).output inc failures if fixup: copyFile(producedHtml, expectedHtml) diff --git a/nimdoc/tester.nim b/nimdoc/tester.nim index 5262952224f78..9daa0bb51e514 100644 --- a/nimdoc/tester.nim +++ b/nimdoc/tester.nim @@ -3,6 +3,7 @@ # to change expected results (after carefully verifying everything), use -d:fixup import strutils, os +from std/private/gitutils import diffFiles var failures = 0 @@ -40,7 +41,7 @@ proc testNimDoc(prjDir, docsDir: string; switches: NimSwitches; fixup = false) = inc failures elif readFile(expected) != readFile(produced): echo "FAILURE: files differ: ", produced - discard execShellCmd("diff -uNdr " & expected & " " & produced) + echo diffFiles(expected, produced).output inc failures if fixup: copyFile(produced, expected) diff --git a/nimpretty/tester.nim b/nimpretty/tester.nim index 0a60ce6935ce2..b1f15aee615ad 100644 --- a/nimpretty/tester.nim +++ b/nimpretty/tester.nim @@ -1,6 +1,7 @@ # Small program that runs the test cases import strutils, os, sequtils +from std/private/gitutils import diffFiles const dir = "nimpretty/tests" @@ -26,7 +27,7 @@ proc test(infile, ext: string) = let produced = dir / nimFile.changeFileExt(ext) if readFile(expected) != readFile(produced): echo "FAILURE: files differ: ", nimFile - discard execShellCmd("diff -uNdr " & expected & " " & produced) + echo diffFiles(expected, produced).output failures += 1 else: echo "SUCCESS: files identical: ", nimFile @@ -43,7 +44,7 @@ proc testTogether(infiles: seq[string]) = let produced = dir / "outputdir" / infile if readFile(expected) != readFile(produced): echo "FAILURE: files differ: ", nimFile - discard execShellCmd("diff -uNdr " & expected & " " & produced) + echo diffFiles(expected, produced).output failures += 1 else: echo "SUCCESS: files identical: ", nimFile diff --git a/testament/categories.nim b/testament/categories.nim index ffee5eeb39d95..f1dee35708f03 100644 --- a/testament/categories.nim +++ b/testament/categories.nim @@ -665,8 +665,8 @@ proc runJoinedTest(r: var TResults, cat: Category, testsDir: string, options: st if buf != outputExpected: writeFile(outputExceptedFile, outputExpected) - discard execShellCmd("diff -uNdr $1 $2" % [outputExceptedFile, outputGottenFile]) - echo failString & "megatest output different!" + echo diffFiles(outputGottenFile, outputExceptedFile).output + echo failString & "megatest output different, see $1 vs $2" % [outputGottenFile, outputExceptedFile] # outputGottenFile, outputExceptedFile not removed on purpose for debugging. quit 1 else: diff --git a/testament/testament.nim b/testament/testament.nim index 9caa3f6b9beca..0607ac41d1694 100644 --- a/testament/testament.nim +++ b/testament/testament.nim @@ -17,6 +17,7 @@ from std/sugar import dup import compiler/nodejs import lib/stdtest/testutils from lib/stdtest/specialpaths import splitTestFile +from std/private/gitutils import diffStrings proc trimUnitSep(x: var string) = let L = x.len @@ -307,7 +308,7 @@ proc addResult(r: var TResults, test: TTest, target: TTarget, maybeStyledEcho styleBright, expected, "\n" maybeStyledEcho fgYellow, "Gotten:" maybeStyledEcho styleBright, given, "\n" - + echo diffStrings(expected, given).output if backendLogging and (isAppVeyor or isAzure): let (outcome, msg) = From a5c3253716fc42aeb8b3905b3bd2a1c5fd2812af Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Thu, 29 Apr 2021 02:33:38 -0700 Subject: [PATCH 05/12] refactor with createTempDir --- lib/std/tempfiles.nim | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/std/tempfiles.nim b/lib/std/tempfiles.nim index c9fff0e7f8502..9f954679a425c 100644 --- a/lib/std/tempfiles.nim +++ b/lib/std/tempfiles.nim @@ -104,7 +104,8 @@ proc createTempFile*(prefix, suffix: string, dir = ""): tuple[fd: File, path: st ## Creates a new temporary file in the directory `dir`. ## ## This generates a path name using `genTempPath(prefix, suffix, dir)` and - ## returns a file handle to an open file and the path of that file. + ## returns a file handle to an open file and the path of that file, possibly after + ## retrying to ensure it doesn't already exist. ## ## If failing to create a temporary file, `IOError` will be raised. ## @@ -126,12 +127,11 @@ proc createTempFile*(prefix, suffix: string, dir = ""): tuple[fd: File, path: st raise newException(IOError, "Failed to create a temporary file under directory " & dir) proc createTempDir*(prefix, suffix: string, dir = ""): string = - ## `createTempDir` creates a new temporary directory in the directory `dir`. + ## Creates a new temporary directory in the directory `dir`. ## - ## If `dir` is the empty string, the default directory for temporary files - ## (`getTempDir `_) will be used. - ## The temporary directory name begins with `prefix` and ends with `suffix`. - ## `createTempDir` returns the path of that temporary firectory. + ## This generates a dir name using `genTempPath(prefix, suffix, dir)`, creates + ## the directory and returns it, possibly after retrying to ensure it doesn't + ## already exist. ## ## If failing to create a temporary directory, `IOError` will be raised. ## @@ -144,7 +144,7 @@ proc createTempDir*(prefix, suffix: string, dir = ""): string = createDir(dir) for i in 0 ..< maxRetry: - result = dir / (prefix & randomPathName(nimTempPathLength) & suffix) + result.path = genTempPath(prefix, suffix, dir) try: if not existsOrCreateDir(result): return From 03fffae81e88b57d378b35381417e5548689b54f Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Thu, 29 Apr 2021 02:38:14 -0700 Subject: [PATCH 06/12] cleanup --- lib/std/tempfiles.nim | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/lib/std/tempfiles.nim b/lib/std/tempfiles.nim index 9f954679a425c..fc70e21b1d214 100644 --- a/lib/std/tempfiles.nim +++ b/lib/std/tempfiles.nim @@ -90,14 +90,17 @@ template randomPathName(length: Natural): string = res[i] = state.sample(letters) res +proc getTempDirImpl(dir: string): string = + result = dir + if result.len == 0: + result = getTempDir() + proc genTempPath*(prefix, suffix: string, dir = ""): string = ## Generates a path name in `dir`. ## ## If `dir` is empty, (`getTempDir `_) will be used. ## The path begins with `prefix` and ends with `suffix`. - var dir = dir - if dir.len == 0: - dir = getTempDir() + let dir = getTempDirImpl(dir) result = dir / (prefix & randomPathName(nimTempPathLength) & suffix) proc createTempFile*(prefix, suffix: string, dir = ""): tuple[fd: File, path: string] = @@ -110,12 +113,8 @@ proc createTempFile*(prefix, suffix: string, dir = ""): tuple[fd: File, path: st ## If failing to create a temporary file, `IOError` will be raised. ## ## .. note:: It is the caller's responsibility to remove the file when no longer needed. - var dir = dir - if dir.len == 0: - dir = getTempDir() - + let dir = getTempDirImpl(dir) createDir(dir) - for i in 0 ..< maxRetry: result.path = genTempPath(prefix, suffix, dir) try: @@ -136,13 +135,8 @@ proc createTempDir*(prefix, suffix: string, dir = ""): string = ## If failing to create a temporary directory, `IOError` will be raised. ## ## .. note:: It is the caller's responsibility to remove the directory when no longer needed. - ## - var dir = dir - if dir.len == 0: - dir = getTempDir() - + let dir = getTempDirImpl(dir) createDir(dir) - for i in 0 ..< maxRetry: result.path = genTempPath(prefix, suffix, dir) try: From 23207b6d5a08bca51d349749059b3bffdd577323 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Thu, 29 Apr 2021 02:39:19 -0700 Subject: [PATCH 07/12] refacotr --- lib/std/tempfiles.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/std/tempfiles.nim b/lib/std/tempfiles.nim index fc70e21b1d214..e7637c4e653fa 100644 --- a/lib/std/tempfiles.nim +++ b/lib/std/tempfiles.nim @@ -138,7 +138,7 @@ proc createTempDir*(prefix, suffix: string, dir = ""): string = let dir = getTempDirImpl(dir) createDir(dir) for i in 0 ..< maxRetry: - result.path = genTempPath(prefix, suffix, dir) + result = genTempPath(prefix, suffix, dir) try: if not existsOrCreateDir(result): return From 28cf312956065a716f1ee6f3ef623976449530c7 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Thu, 29 Apr 2021 02:41:28 -0700 Subject: [PATCH 08/12] fixup --- lib/std/tempfiles.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/std/tempfiles.nim b/lib/std/tempfiles.nim index e7637c4e653fa..91a3ce7f3a877 100644 --- a/lib/std/tempfiles.nim +++ b/lib/std/tempfiles.nim @@ -90,7 +90,7 @@ template randomPathName(length: Natural): string = res[i] = state.sample(letters) res -proc getTempDirImpl(dir: string): string = +proc getTempDirImpl(dir: string): string {.inline.} = result = dir if result.len == 0: result = getTempDir() From 13fdaab91149d468839dbfc8d99dd7755c28523a Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Thu, 29 Apr 2021 12:37:40 -0700 Subject: [PATCH 09/12] fixup --- lib/std/private/gitutils.nim | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/std/private/gitutils.nim b/lib/std/private/gitutils.nim index 16eaf3580fcfe..49fcf1d6cf554 100644 --- a/lib/std/private/gitutils.nim +++ b/lib/std/private/gitutils.nim @@ -62,8 +62,6 @@ proc diffStrings*(a, b: string): tuple[output: string, same: bool] = echo diffStrings(a, b).output template tmpFileImpl(prefix, str): auto = - # pending https://github.com/nim-lang/Nim/pull/17889 - # let (fd, path) = createTempFile(prefix, "") let path = genTempPath(prefix, "") writeFile(path, str) path From 57dc8d642dce6c1127c98b7cbc9edbfe747d4047 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Thu, 29 Apr 2021 12:41:16 -0700 Subject: [PATCH 10/12] PRTEMP fake test spec changes to show effect of diffStrings --- nimdoc/testproject/expected/testproject.html | 4 ++-- tests/concepts/tconcepts_issues.nim | 2 +- tests/osproc/treadlines.nim | 3 ++- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/nimdoc/testproject/expected/testproject.html b/nimdoc/testproject/expected/testproject.html index 1ea9e172aa2f0..b9ef507d24285 100644 --- a/nimdoc/testproject/expected/testproject.html +++ b/nimdoc/testproject/expected/testproject.html @@ -44,7 +44,7 @@ localStorage.setItem('theme', 'light'); } } - + PRTEMP FAKE toggleSwitch.addEventListener('change', switchTheme, false); const currentTheme = localStorage.getItem('theme') ? localStorage.getItem('theme') : null; @@ -57,7 +57,7 @@ } } -window.addEventListener('DOMContentLoaded', main); +window.addEventListener('DOMContentLoaded', main); PRTEMP FAKE diff --git a/tests/concepts/tconcepts_issues.nim b/tests/concepts/tconcepts_issues.nim index c76049bddefe9..fd3ddb371ba0e 100644 --- a/tests/concepts/tconcepts_issues.nim +++ b/tests/concepts/tconcepts_issues.nim @@ -19,7 +19,7 @@ true true true true -p has been called. +p has been called. PRTEMP FAKE VAL to show effect of diffStrings p has been called. implicit generic generic diff --git a/tests/osproc/treadlines.nim b/tests/osproc/treadlines.nim index bcde19d7f15f5..e71ca5e23abe0 100644 --- a/tests/osproc/treadlines.nim +++ b/tests/osproc/treadlines.nim @@ -1,6 +1,7 @@ discard """ output: ''' -Error: cannot open 'a.nim'\31 +Error: cannot open 'a.nim' +PRTEMP FAKE Error: cannot open 'b.nim'\31 ''' targets: "c" From 04a4c902df90abf0f38375961267d90cf9c2fc05 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Thu, 29 Apr 2021 18:07:07 -0700 Subject: [PATCH 11/12] add runnableExamples for experimental/diff + cross-reference with gitutils --- lib/experimental/diff.nim | 45 +++++++++++++++++++----------------- lib/std/private/gitutils.nim | 11 ++++++--- 2 files changed, 32 insertions(+), 24 deletions(-) diff --git a/lib/experimental/diff.nim b/lib/experimental/diff.nim index ba4e8ad64da43..ea0a5cfb841eb 100644 --- a/lib/experimental/diff.nim +++ b/lib/experimental/diff.nim @@ -10,28 +10,31 @@ ## This module implements an algorithm to compute the ## `diff`:idx: between two sequences of lines. ## -## A basic example of `diffInt` on 2 arrays of integers: -## -## .. code:: Nim -## -## import experimental/diff -## echo diffInt([0, 1, 2, 3, 4, 5, 6, 7, 8], [-1, 1, 2, 3, 4, 5, 666, 7, 42]) -## -## Another short example of `diffText` to diff strings: -## -## .. code:: Nim -## -## import experimental/diff -## # 2 samples of text for testing (from "The Call of Cthulhu" by Lovecraft) -## let txt0 = """I have looked upon all the universe has to hold of horror, -## even skies of spring and flowers of summer must ever be poison to me.""" -## let txt1 = """I have looked upon all your code has to hold of bugs, -## even skies of spring and flowers of summer must ever be poison to me.""" -## -## echo diffText(txt0, txt1) -## ## - To learn more see `Diff on Wikipedia. `_ +runnableExamples: + assert diffInt( + [0, 1, 2, 3, 4, 5, 6, 7, 8], + [-1, 1, 2, 3, 4, 5, 666, 7, 42]) == + @[Item(startA: 0, startB: 0, deletedA: 1, insertedB: 1), + Item(startA: 6, startB: 6, deletedA: 1, insertedB: 1), + Item(startA: 8, startB: 8, deletedA: 1, insertedB: 1)] + +runnableExamples: + # 2 samples of text (from "The Call of Cthulhu" by Lovecraft) + let txt0 = """ +abc +def ghi +jkl2""" + let txt1 = """ +bacx +abc +def ghi +jkl""" + assert diffText(txt0, txt1) == + @[Item(startA: 0, startB: 0, deletedA: 0, insertedB: 1), + Item(startA: 2, startB: 3, deletedA: 1, insertedB: 1)] + # code owner: Arne Döring # # This is based on C# code written by Matthias Hertel, http://www.mathertel.de @@ -309,7 +312,7 @@ proc diffText*(textA, textB: string): seq[Item] = ## `textB` B-version of the text (usually the new one) ## ## Returns a seq of Items that describe the differences. - + # See also `gitutils.diffStrings`. # prepare the input-text and convert to comparable numbers. var h = initTable[string, int]() # TextA.len + TextB.len <- probably wrong initial size # The A-Version of the data (original data) to be compared. diff --git a/lib/std/private/gitutils.nim b/lib/std/private/gitutils.nim index 49fcf1d6cf554..5bcd9e377bb60 100644 --- a/lib/std/private/gitutils.nim +++ b/lib/std/private/gitutils.nim @@ -40,14 +40,20 @@ proc isGitRepo*(dir: string): bool = result = status == 0 and output.strip() == "" proc diffFiles*(path1, path2: string): tuple[output: string, same: bool] = - # could be customized, e.g. non-git diff with `diff -uNdr`, or with git diff options (e.g. --color-moved, --word-diff). - # in general, git diff has more options. + ## Returns a human readable diff of files `path1`, `path2`, the exact form of + ## which is implementation defined. + # This could be customized, e.g. non-git diff with `diff -uNdr`, or with + # git diff options (e.g. --color-moved, --word-diff). + # in general, `git diff` has more options than `diff`. var status = 0 (result.output, status) = execCmdEx("git diff --no-index $1 $2" % [path1.quoteShell, path2.quoteShell]) doAssert (status == 0) or (status == 1) result.same = status == 0 proc diffStrings*(a, b: string): tuple[output: string, same: bool] = + ## Returns a human readable diff of `a`, `b`, the exact form of which is + ## implementation defined. + ## See also `experimental.diff`. runnableExamples: let a = "ok1\nok2\nok3\n" let b = "ok1\nok2 alt\nok3\nok4\n" @@ -55,7 +61,6 @@ proc diffStrings*(a, b: string): tuple[output: string, same: bool] = doAssert not same let (c2, same2) = diffStrings(a, a) doAssert same2 - runnableExamples("-r:off"): let a = "ok1\nok2\nok3\n" let b = "ok1\nok2 alt\nok3\nok4\n" From 0c52015c3c26cf1d0e6dee418bb9a6317733dfc4 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Thu, 29 Apr 2021 18:16:28 -0700 Subject: [PATCH 12/12] Revert "PRTEMP fake test spec changes to show effect of diffStrings" This reverts commit 57dc8d642dce6c1127c98b7cbc9edbfe747d4047. --- nimdoc/testproject/expected/testproject.html | 4 ++-- tests/concepts/tconcepts_issues.nim | 2 +- tests/osproc/treadlines.nim | 3 +-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/nimdoc/testproject/expected/testproject.html b/nimdoc/testproject/expected/testproject.html index b9ef507d24285..1ea9e172aa2f0 100644 --- a/nimdoc/testproject/expected/testproject.html +++ b/nimdoc/testproject/expected/testproject.html @@ -44,7 +44,7 @@ localStorage.setItem('theme', 'light'); } } - PRTEMP FAKE + toggleSwitch.addEventListener('change', switchTheme, false); const currentTheme = localStorage.getItem('theme') ? localStorage.getItem('theme') : null; @@ -57,7 +57,7 @@ } } -window.addEventListener('DOMContentLoaded', main); PRTEMP FAKE +window.addEventListener('DOMContentLoaded', main); diff --git a/tests/concepts/tconcepts_issues.nim b/tests/concepts/tconcepts_issues.nim index fd3ddb371ba0e..c76049bddefe9 100644 --- a/tests/concepts/tconcepts_issues.nim +++ b/tests/concepts/tconcepts_issues.nim @@ -19,7 +19,7 @@ true true true true -p has been called. PRTEMP FAKE VAL to show effect of diffStrings +p has been called. p has been called. implicit generic generic diff --git a/tests/osproc/treadlines.nim b/tests/osproc/treadlines.nim index e71ca5e23abe0..bcde19d7f15f5 100644 --- a/tests/osproc/treadlines.nim +++ b/tests/osproc/treadlines.nim @@ -1,7 +1,6 @@ discard """ output: ''' -Error: cannot open 'a.nim' -PRTEMP FAKE +Error: cannot open 'a.nim'\31 Error: cannot open 'b.nim'\31 ''' targets: "c"