From 805e176750a86f806526dba7c250d928d24025ba Mon Sep 17 00:00:00 2001 From: Rod Vagg Date: Fri, 10 Sep 2021 17:15:22 +1000 Subject: [PATCH] fix: handle windows crlf with more brutality Ref: https://github.com/warpfork/go-testmark/pull/3 --- .gitattributes | 2 -- README.md | 9 ++------- parse.js | 5 ++++- test/test-parse.js | 17 +++++++++++++++-- types/parse.d.ts.map | 2 +- 5 files changed, 22 insertions(+), 13 deletions(-) delete mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index fb9a97d..0000000 --- a/.gitattributes +++ /dev/null @@ -1,2 +0,0 @@ -* text=auto -*.* text eol=lf diff --git a/README.md b/README.md index 77968dd..9d95152 100644 --- a/README.md +++ b/README.md @@ -179,14 +179,9 @@ export interface DirEnt { ## Note regarding Windows -We're relying on text files and want to have byte-perfect representations of test fixtures, but this presents some problems for Windows. By default (unless the user has changed the settings), git on Windows will convert line endings to Windows style which include a carriage return (`\r`) character. This isn't good, because we don't know whether these characters are part of our fixture data or not! +Ideally when we're relying on text files for test data input we'd want to have byte-perfect representations of fixtures, but this presents some problems for Windows. By default (unless the user has changed the settings), git on Windows will convert line endings to Windows style which include a carriage return (`\r`) character. This isn't good, because we don't know whether these characters are part of our fixture data or not! -Our recommendation if you expect to support Windows users, or have Windows users try and run your tests, is to add a `.gitattributes` file to your Git project that uses testmark with something like the following: - -``` -* text=auto -*.* text eol=lf -``` +So, testmark takes a rather brute-force approach to this problem and just strips out carriage return characters when they appear with a line-ending. In practice this _may_ impact the byte-perfect requirements for test fixtures, so you should be careful when using data that strays outside of standard printable character range, especially when control characters get involved. This is a text file format, if your data isn't text, then make it text by encoding in hex or base64 or something that reduces the character set to the safe range. ## Note about the package name diff --git a/parse.js b/parse.js index d187256..a8d97fb 100644 --- a/parse.js +++ b/parse.js @@ -14,10 +14,13 @@ export function parse (original) { throw new TypeError('Expected a Markdown document string') } + // sorry windows users, we're even turning your original to unix + original = original.replace(/\r?\n/g, '\n') + /** @type {Document & {original:string}} */ const doc = { original, - lines: original.split('\n'), // can't split with \r? because we need offsets + lines: original.split('\n'), dataHunks: /** @type {DocHunk[]} */ ([]), hunksByName: new Map() } diff --git a/test/test-parse.js b/test/test-parse.js index 611e26c..5f32c1c 100644 --- a/test/test-parse.js +++ b/test/test-parse.js @@ -32,11 +32,24 @@ const exampleMdExpectedHunks = [ ] describe('Read', () => { - it('can parse example.md', async () => { + /** @type {string} */ + let exampleMdOriginal + + before(async () => { const exampleMd = new URL('../example.md', import.meta.url) - const exampleMdOriginal = await fs.promises.readFile(exampleMd, 'utf8') + exampleMdOriginal = await fs.promises.readFile(exampleMd, 'utf8') + }) + + it('can parse example.md', async () => { const doc = parse(exampleMdOriginal) assert.deepStrictEqual(exampleMdExpectedHunks, doc.dataHunks) assert.deepStrictEqual(toString(doc), exampleMdOriginal) }) + + it('can parse example.md as windows', async () => { + const exampleMdOriginalWindows = exampleMdOriginal.replace(/\r?\n/g, '\r\n') + const doc = parse(exampleMdOriginalWindows) + assert.deepStrictEqual(exampleMdExpectedHunks, doc.dataHunks) + assert.deepStrictEqual(toString(doc), exampleMdOriginal) + }) }) diff --git a/types/parse.d.ts.map b/types/parse.d.ts.map index f54b1e6..e5b16e1 100644 --- a/types/parse.d.ts.map +++ b/types/parse.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../parse.js"],"names":[],"mappings":"AAEA;;;GAGG;AAEH;;;GAGG;AACH,gCAHW,MAAM,GACJ,QAAQ,CA2EpB;sBAjFY,OAAO,aAAa,EAAE,OAAO;uBAC7B,OAAO,aAAa,EAAE,QAAQ"} \ No newline at end of file +{"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../parse.js"],"names":[],"mappings":"AAEA;;;GAGG;AAEH;;;GAGG;AACH,gCAHW,MAAM,GACJ,QAAQ,CA6EpB;sBAnFY,OAAO,aAAa,EAAE,OAAO;uBAC7B,OAAO,aAAa,EAAE,QAAQ"} \ No newline at end of file