Repository: kpdecker/jsdiff (JavaScript)

Issue:
Applying a patch doesn't seem to work?
```javascript
[const jsdiff = require("diff");

let text = `# Markdown
This is some markdown.

Let's find the diffs
`;

let newText = `# Markdown
This is some markdown.

Let's find the diffs and prove it all works.
`;
let diff = jsdiff.structuredPatch("old", "new", text, newText);
let newDoc = jsdiff.applyPatch(text, diff);
console.log(newDoc);
```

and what I get back is:

```
/home/nicferrier/jswork/sqlparsing/node_modules/diff/lib/patch/apply.js:111
          delimiter = _hunk.linedelimiters[j];
                                          ^

TypeError: Cannot read property '0' of undefined
    at Object.applyPatch (/home/nicferrier/jswork/sqlparsing/node_modules/diff/lib/patch/apply.js:111:43)
```

I couldn't find a test that does this... but since structuredPatch is at the heart of all the patch routines that seems a bit odd.

Help?


Discussion:
I did some digging:

```javascript
const {applyPatch, applyPatches} = require("./lib/patch/apply.js");

const {parsePatch} = require('./lib/patch/parse.js');
const {createPatch, structuredPatch} = require('./lib/patch/create.js');


let text = `# Markdown
This is some markdown.

Let's find the diffs
`;

let newText = `# Markdown
This is some markdown.

Let's find the diffs and prove it all works.
`;

let patch = createPatch("file", text, newText);
console.log("patch", patch);

let parsed = parsePatch(patch);
console.log("parsed", JSON.stringify(parsed, null, 2));

let newDoc = applyPatch(text, parsed);
console.log(newDoc);

let structuredParsed = structuredPatch("old", "new", text, newText);
console.log("structured", JSON.stringify(structuredParsed, null, 2));
```

This is what the above produces:

```
patch Index: file
===================================================================
--- file
+++ file
@@ -1,4 +1,4 @@
 # Markdown
 This is some markdown.

-Let's find the diffs
+Let's find the diffs and prove it all works.

parsed [
  {
    "index": "file",
    "oldFileName": "file",
    "oldHeader": "",
    "newFileName": "file",
    "newHeader": "",
    "hunks": [
      {
        "oldStart": 1,
        "oldLines": 4,
        "newStart": 1,
        "newLines": 4,
        "lines": [
          " # Markdown",
          " This is some markdown.",
          " ",
          "-Let's find the diffs",
          "+Let's find the diffs and prove it all works."
        ],
        "linedelimiters": [
          "\n",
          "\n",
          "\n",
          "\n",
          "\n"
        ]
      }
    ]
  }
]
# Markdown
This is some markdown.

Let's find the diffs and prove it all works.

structured {
  "oldFileName": "old",
  "newFileName": "new",
  "hunks": [
    {
      "oldStart": 1,
      "oldLines": 4,
      "newStart": 1,
      "newLines": 4,
      "lines": [
        " # Markdown",
        " This is some markdown.",
        " ",
        "-Let's find the diffs",
        "+Let's find the diffs and prove it all works."
      ]
    }
  ]
}
```

So the object produced by `parsePatch` differs from that produced by `structuredPatch`. That was not my expectation and maybe is the problem.

I can use the parsePatch form right now so I'm good.

Thanks!
Would be great if this was fixed. I was surprised by this as well and the type definitions also indicate this should work.
It looks like `linedelimiters` is simply not populated when creating a structuredPatch. Populating it makes structuredPatch work.
This is also happening in `merge`
Appears to be related to #157 

I've used an approach along these lines to work around the issue for now

```
diffs.hunks.forEach(hunk => hunk.linedelimiters = Array(hunk.lines.length).fill('\n'));
```
@nicferrier @okev  This thread might not be the correct one, but could anyone point me in the direction of how can I represent (with the help of `ins` and `del` tags) the diff between two markdown using this structured patch? Also is there a way to determine word changes using this method, as I see that if a line is same with difference in a word the whole line is marked as removed with `-`.




Patch:
diff --git a/src/patch/apply.js b/src/patch/apply.js
index 4cf0ddf0..269a5792 100644
--- a/src/patch/apply.js
+++ b/src/patch/apply.js
@@ -89,7 +89,7 @@ export function applyPatch(source, uniDiff, options = {}) {
       let line = hunk.lines[j],
           operation = (line.length > 0 ? line[0] : ' '),
           content = (line.length > 0 ? line.substr(1) : line),
-          delimiter = hunk.linedelimiters[j];
+          delimiter = hunk.linedelimiters && hunk.linedelimiters[j] || '\n';
 
       if (operation === ' ') {
         toPos++;


Test patch:
diff --git a/test/patch/apply.js b/test/patch/apply.js
index 65187155..d5b06ace 100755
--- a/test/patch/apply.js
+++ b/test/patch/apply.js
@@ -1,6 +1,7 @@
 import {applyPatch, applyPatches} from '../../lib/patch/apply';
 import {parsePatch} from '../../lib/patch/parse';
 import {createPatch} from '../../lib/patch/create';
+import {structuredPatch} from '../../lib/patch/create';
 
 import {expect} from 'chai';
 
@@ -721,7 +722,20 @@ describe('patch/apply', function() {
       expect(applyPatch(oldtext, diffed)).to.equal(newtext);
     });
 
+    it('should accept structured patches', function() {
+      const oldContent = [
+        'line1',
+        'line2',
+        ''
+      ].join('\n');
+      const newContent = [
+        'line1',
+        'line02'
+      ].join('\n');
+      const patch = structuredPatch('test.txt', 'test.txt', oldContent, newContent);
 
+      expect(applyPatch(oldContent, patch)).to.equal(newContent);
+    });
   });
 
   describe('#applyPatches', function() {