jenkins-bot has submitted this change and it was merged.

Change subject: Use async serializeDOM in jsapi
......................................................................


Use async serializeDOM in jsapi

 * Replace uses of (sync) `toString` with an (async) `toWikitext` method.

 * Follow up to Id68d24007229dcfa0bf6fb16c6ed3ecdaad0c2e5 where these
   tests were skipped.

Change-Id: I33717f9261885bd121aef27360602fe8ebbc8ccb
---
M guides/jsapi/README.md
M lib/jsapi.js
M tests/mocha/jsapi.js
3 files changed, 269 insertions(+), 80 deletions(-)

Approvals:
  Cscott: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/guides/jsapi/README.md b/guides/jsapi/README.md
index 5ff6dcf..4df3b5a 100644
--- a/guides/jsapi/README.md
+++ b/guides/jsapi/README.md
@@ -12,7 +12,20 @@
 exports vanilla [`Promise`]s if you wish to maintain compatibility
 with old versions of `node` at the cost of a little bit of readability.
 
-Use as a wikitext parser is straightforward (where `text` is
+Since many methods in the API return [`Promise`]s, we've also provided
+a [`Promise`]-aware REPL, that will wait for a promise to be resolved
+before printing its value.  This can be started from the
+shell using:
+
+       node -e 'require("parsoid").repl()'
+
+Use `"./"` instead of `"parsoid"` if you are running this from a
+checked-out repository.  Code examples below which contain lines
+starting with `>` show sessions using this REPL.  (You may also
+wish to look in `tests/mocha/jsapi.js` for examples using a more
+traditional promise-chaining style.)
+
+Use of Parsoid as a wikitext parser is straightforward (where `text` is
 wikitext input):
 
        #/usr/bin/node --harmony-generators
@@ -29,8 +42,8 @@
        main().done();
 
 As you can see, there is a little bit of boilerplate needed to get the
-asynchronous machinery started.  Future code examples will be assumed
-to replace the body of the `main()` method above.
+asynchronous machinery started.  The body of the `main()` method can
+be replaced with your code.
 
 The `pdoc` variable above holds a [`PDoc`] object, which has
 helpful methods to filter and manipulate the document.  If you want
@@ -46,29 +59,29 @@
 
        > var text = "I has a template! {{foo|bar|baz|eggs=spam}} See it?\n";
        > var pdoc = yield Parsoid.parse(text, { pdoc: true });
-       > console.log(String(pdoc));
+       > console.log(yield pdoc.toWikitext());
        I has a template! {{foo|bar|baz|eggs=spam}} See it?
        > var templates = pdoc.filterTemplates();
-       > console.log(templates.map(String));
+       > console.log(yield Promise.map(templates, Parsoid.toWikitext));
        [ '{{foo|bar|baz|eggs=spam}}' ]
        > var template = templates[0];
        > console.log(template.name);
        foo
        > template.name = 'notfoo';
-       > console.log(String(template));
+       > console.log(yield template.toWikitext());
        {{notfoo|bar|baz|eggs=spam}}
        > console.log(template.params.map(function(p) { return p.name; }));
        [ '1', '2', 'eggs' ]
-       > console.log(template.get(1).value);
+       > console.log(yield template.get(1).value.toWikitext());
        bar
-       > console.log(template.get("eggs").value);
+       > console.log(yield template.get("eggs").value.toWikitext());
        spam
 
 Getting nested templates is trivial:
 
        > var text = "{{foo|bar={{baz|{{spam}}}}}}";
        > var pdoc = yield Parsoid.parse(text, { pdoc: true });
-       > console.log(pdoc.filterTemplates().map(String));
+       > console.log(yield Promise.map(pdoc.filterTemplates(), 
Parsoid.toWikitext));
        [ '{{foo|bar={{baz|{{spam}}}}}}',
          '{{baz|{{spam}}}}',
          '{{spam}}' ]
@@ -82,15 +95,15 @@
        > var text = "{{foo|this {{includes a|template}}}}";
        > var pdoc = yield Parsoid.parse(text, { pdoc: true });
        > var templates = pdoc.filterTemplates({ recursive: false });
-       > console.log(templates.map(String));
+       > console.log(yield Promise.map(templates, Parsoid.toWikitext));
        [ '{{foo|this {{includes a|template}}}}' ]
        > var foo = templates[0];
-       > console.log(String(foo.get(1).value));
+       > console.log(yield foo.get(1).value.toWikitext());
        this {{includes a|template}}
        > var more = foo.get(1).value.filterTemplates();
-       > console.log(more.map(String));
+       > console.log(yield Promise.map(more, Parsoid.toWikitext));
        [ '{{includes a|template}}' ]
-       > console.log(String(more[0].get(1).value));
+       > console.log(yield more[0].get(1).value.toWikitext());
        template
 
 Templates can be easily modified to add, remove, or alter params.
@@ -108,13 +121,14 @@
        ...        template.name = 'bar-stub';
        ...    }
        ... });
-       > console.log(String(pdoc));
+       > console.log(yield pdoc.toWikitext());
        {{cleanup|date = July 2012}} '''Foo''' is a [[bar]]. {{bar-stub}}
 
 At any time you can convert the `pdoc` into HTML conforming to the
 [MediaWiki DOM spec] (by referencing the
 [`document`](#!/api/PDoc-property-document) property) or into wikitext (by
-invoking [`toString()`](#!/api/PNodeList-method-toString)).  This allows you
+invoking [`toWikitext()`](#!/api/PNodeList-method-toWikitext), which
+returns a [`Promise`] for the wikitext string).  This allows you
 to save the page using either standard API methods or the RESTBase API
 (once [T101501](https://phabricator.wikimedia.org/T101501) is resolved).
 
diff --git a/lib/jsapi.js b/lib/jsapi.js
index 252bacf..b804745 100644
--- a/lib/jsapi.js
+++ b/lib/jsapi.js
@@ -10,7 +10,9 @@
 // PExtLink#url PWikiLink#title should handle mw:ExpandedAttrs
 // make separate package?
 
+var Promise = require('prfun');
 var util = require('util');
+
 var DOMImpl = require('domino').impl;
 var Node = DOMImpl.Node;
 var NodeFilter = DOMImpl.NodeFilter;
@@ -19,11 +21,6 @@
 
 // WTS helper
 var wts = function(env, nodes) {
-       // XXX: Serializing to wikitext is very user-friendly, but it depends on
-       // WTS.serializeDOMSync which we might not want to keep around forever.
-       // An alternative would be:
-       //    return DU.normalizeOut(node, 'parsoidOnly');
-       // which might be almost as friendly.
        var body;
        if (nodes.length === 0) {
                return '';
@@ -35,8 +32,39 @@
                        body.appendChild(nodes[i].cloneNode(true));
                }
        }
-       // FXIME: serializeDOMSync is dead.
-       return (new WikitextSerializer({ env: env })).serializeDOMSync(body);
+       return (new WikitextSerializer({ env: env })).serializeDOM(body);
+};
+
+// toString helper
+var toStringHelper = function(nodes, sizeLimit) {
+       var out;
+       if (sizeLimit === undefined) { sizeLimit = 80; /* characters */ }
+       if (nodes.length === 0) {
+               return '';
+       } else if (nodes.length === 1) {
+               var body = nodes[0].ownerDocument.createElement('body');
+               body.appendChild(nodes[0].cloneNode(true));
+               out = DU.normalizeOut(body, 'parsoidOnly');
+               if (out.length <= sizeLimit || !DU.isElt(nodes[0])) { return 
out; }
+               body.firstChild.innerHTML = '...';
+               out = DU.normalizeOut(body, 'parsoidOnly');
+               if (out.length <= sizeLimit) { return out; }
+               var name = nodes[0].nodeName.toLowerCase();
+               var children = nodes[0].childNodes;
+               if (children.length === 0) {
+                       return '<' + name + ' .../>';
+               } else {
+                       return '<' + name + ' ...>...</' + name + '>';
+               }
+       } else {
+               for (var i = 0; i < nodes.length; i++) {
+                       out += toStringHelper(
+                               [nodes[i]],
+                               (sizeLimit - out.length) / (nodes.length - i)
+                       );
+               }
+               return out;
+       }
 };
 
 // Forward declarations of Wrapper classes.
@@ -425,11 +453,21 @@
        }, },
 
        /**
-        * Return a string representing the contents of this object as wikitext.
+        * Return a promise for a string representing the contents of this
+        * object as wikitext.
+        * @return {Promise}
+        */
+       toWikitext: { value: Promise.method(function() {
+               return wts(this.pdoc.env, this.nodes);
+       }), },
+
+       /**
+        * Return a string representing the contents of this object for
+        * debugging.  Some contents may be elided.
         * @return {String}
         */
        toString: { value: function() {
-               return wts(this.pdoc.env, this.nodes);
+               return toStringHelper(this.nodes);
        }, },
 });
 /**
@@ -472,7 +510,7 @@
  *   A function which will be invoked when {@link #update} is called.
  * @param {Function} [opts.wtsNodes]
  *   A function returning an array of {@link Node}s which can tweak the
- *   portion of the document serialized by {@link #toString}.
+ *   portion of the document serialized by {@link #toWikitext}.
  */
 PNode = function PNode(pdoc, parent, node, opts) {
        /** @property {PDoc} pdoc The parent document for this {@link PNode}. */
@@ -531,12 +569,20 @@
                return nodes.map(function(n) { return n.outerHTML; }).join('');
        }, },
        /**
+        * @inheritdoc PNodeList#toWikitext
+        * @method
+        */
+       toWikitext: { value: Promise.method(function() {
+               var nodes = this._wtsNodes ? this._wtsNodes() : [ this.node ];
+               return wts(this.pdoc.env, nodes);
+       }), },
+       /**
         * @inheritdoc PNodeList#toString
         * @method
         */
        toString: { value: function() {
                var nodes = this._wtsNodes ? this._wtsNodes() : [ this.node ];
-               return wts(this.pdoc.env, nodes);
+               return toStringHelper(nodes);
        }, },
 });
 
@@ -1164,6 +1210,15 @@
                        this._value.update();
                },
        },
+       toWikitext: { value: Promise.method(function() {
+               var k = this.key;
+               return Promise.join(
+                       k ? k.toWikitext() : this.name,
+                       this.value.toWikitext()
+               ).spread(function(keyWikitext, valueWikitext) {
+                       return keyWikitext + '=' + valueWikitext;
+               });
+       }), },
        toString: { value: function() {
                var k = this.key;
                return (k ? String(k) : this.name) + '=' + String(this.value);
@@ -1269,7 +1324,7 @@
  * instance of {@link PNodeList}, you can filter it, mutate it, etc.
  * But it also provides means to serialize the document as either
  * HTML (via {@link #document} or {@link #toHtml}) or wikitext
- * (via {@link #toString}).
+ * (via {@link #toWikitext}).
  * @class
  * @extends PNodeList
  * @alternateClassName Parsoid.PDoc
@@ -1306,6 +1361,44 @@
        }, },
 });
 
+// Promise-using REPL, for easier debugging.
+// We also handle `yield`, at least in common cases.
+var repl = function() {
+       /* jshint evil:true */
+       // The older version of jshint on jenkins is confused.
+       var Parsoid = require('../');
+       console.log('Parsoid REPL', Parsoid.version);
+       var r = require('repl').start({ ignoreUndefined: true });
+       // `var Parsoid = require('parsoid');` by default.
+       r.context.Parsoid = Parsoid;
+       // `var Promise = require('prfun');` by default.
+       r.context.Promise = Promise;
+       // Patch the `eval` method to wait for Promises to be resolved.
+       var oldEval = r.eval;
+       r.eval = function(cmd, context, filename, callback) {
+               // If `cmd` mentions `yield`, wrap it in a `function*`
+               if (/\byield\b/.test(cmd)) {
+                       // Hack to support `var xyz = yield pdq...;`, convert it
+                       // to `var xyz; ...{ xyz = yield pdq...; }...`
+                       var m = /^(var\s+)(\w+)\s*=/.exec(cmd);
+                       if (m) { cmd = cmd.slice(m[1].length); }
+                       cmd = 'Promise.async(function*(){' + cmd + '})();';
+                       if (m) { cmd = m[1] + m[2] + ';' + cmd; }
+               }
+               oldEval.call(r, cmd, context, filename, function(e, v) {
+                       if (e || !(typeof v === 'object' && typeof v.then === 
'function')) {
+                               return callback(e, v);
+                       }
+                       // OK, this is a promise!  Wait for the result.
+                       v.then(function(v) {
+                               callback(null, v);
+                       }, function(e) {
+                               callback(e);
+                       });
+               });
+       };
+};
+
 module.exports = {
        PDoc: PDoc,
        PNodeList: PNodeList,
@@ -1319,4 +1412,8 @@
        PTemplate: PTemplate,
        PText: PText,
        PWikiLink: PWikiLink,
+       // Helper function for `Promise.map`
+       toWikitext: Promise.method(function(n) { return n.toWikitext(); }),
+       // Useful REPL that handles promises and `yield` well.
+       repl: repl,
 };
diff --git a/tests/mocha/jsapi.js b/tests/mocha/jsapi.js
index 6f11fe7..a60e8a0 100644
--- a/tests/mocha/jsapi.js
+++ b/tests/mocha/jsapi.js
@@ -3,6 +3,7 @@
 "use strict";
 
 var Parsoid = require('../../');
+var Promise = require('prfun');
 
 describe('Parsoid JS API', function() {
        it('converts empty wikitext to HTML', function() {
@@ -22,7 +23,7 @@
        });
 });
 
-describe.skip('Examples from guides/jsapi', function() {
+describe('Examples from guides/jsapi', function() {
        it('converts empty wikitext to HTML', function() {
                return Parsoid.parse('', { pdoc: true}).then(function(pdoc) {
                        pdoc.should.have.property('document');
@@ -38,21 +39,33 @@
        });
        it('filters out templates', function() {
                var text = "I has a template! {{foo|bar|baz|eggs=spam}} See 
it?\n";
-               return Parsoid.parse(text, { pdoc: true }).then(function(pdoc) {
-                       String(pdoc).should.equal(text);
-                       var templates = pdoc.filterTemplates();
+               var pdoc, templates, template;
+               return Parsoid.parse(text, { pdoc: true }).then(function(_pdoc) 
{
+                       pdoc = _pdoc;
+                       return pdoc.toWikitext();
+               }).then(function(wt) {
+                       wt.should.equal(text);
+                       templates = pdoc.filterTemplates();
                        templates.length.should.equal(1);
-                       
String(templates[0]).should.equal('{{foo|bar|baz|eggs=spam}}');
-                       var template = templates[0];
+                       return templates[0].toWikitext();
+               }).then(function(wt) {
+                       wt.should.equal('{{foo|bar|baz|eggs=spam}}');
+                       template = templates[0];
                        template.name.should.equal('foo');
                        template.name = 'notfoo';
-                       
String(template).should.equal('{{notfoo|bar|baz|eggs=spam}}');
+                       return template.toWikitext();
+               }).then(function(wt) {
+                       wt.should.equal('{{notfoo|bar|baz|eggs=spam}}');
                        template.params.length.should.equal(3);
                        template.params[0].name.should.equal('1');
                        template.params[1].name.should.equal('2');
                        template.params[2].name.should.equal('eggs');
-                       String(template.get(1).value).should.equal('bar');
-                       String(template.get('eggs').value).should.equal('spam');
+                       return template.get(1).value.toWikitext();
+               }).then(function(wt) {
+                       wt.should.equal('bar');
+                       return template.get('eggs').value.toWikitext();
+               }).then(function(wt) {
+                       wt.should.equal('spam');
                });
        });
        it('filters templates, recursively', function() {
@@ -66,14 +79,19 @@
        });
        it('filters templates, non-recursively', function() {
                var text = "{{foo|this {{includes a|template}}}}";
+               var foo;
                return Parsoid.parse(text, { pdoc: true }).then(function(pdoc) {
                        var templates = pdoc.filterTemplates({ recursive: false 
});
                        templates.length.should.equal(1);
-                       var foo = templates[0];
-                       String(foo.get(1).value).should.equal('this {{includes 
a|template}}');
+                       foo = templates[0];
+                       return foo.get(1).value.toWikitext();
+               }).then(function(wt) {
+                       wt.should.equal('this {{includes a|template}}');
                        var more = foo.get(1).value.filterTemplates();
                        more.length.should.equal(1);
-                       String(more[0].get(1).value).should.equal('template');
+                       return more[0].get(1).value.toWikitext();
+               }).then(function(wt) {
+                       wt.should.equal('template');
                });
        });
        it('is easy to mutate templates', function() {
@@ -87,12 +105,14 @@
                                        template.name = 'bar-stub';
                                }
                        });
-                       String(pdoc).should.equal("{{cleanup|date = July 2012}} 
'''Foo''' is a [[bar]]. {{bar-stub}}");
+                       return pdoc.toWikitext();
+               }).then(function(wt) {
+                       wt.should.equal("{{cleanup|date = July 2012}} '''Foo''' 
is a [[bar]]. {{bar-stub}}");
                });
        });
 });
 
-describe.skip('Further examples of PDoc API', function() {
+describe('Further examples of PDoc API', function() {
        it('is easy to mutate templates (2)', function() {
                // Works even on nested templates!
                var text = "{{echo|{{cleanup}} '''Foo''' is a [[bar]].}} 
{{uncategorized}}";
@@ -105,7 +125,9 @@
                                        template.add('test2', 
Parsoid.PNodeList.fromHTML(pdoc, "I'm so <b>bold</b>!"));
                                }
                        });
-                       String(pdoc).should.equal("{{echo|{{cleanup|date = July 
2012|test1 = <nowiki>{{foo}}</nowiki>&bar{{!}}bat<nowiki><p></nowiki>|test2 = 
I'm so '''bold'''!}} '''Foo''' is a [[bar]].}} {{uncategorized}}");
+                       return pdoc.toWikitext();
+               }).then(function(wt) {
+                       wt.should.equal("{{echo|{{cleanup|date = July 
2012|test1 = <nowiki>{{foo}}</nowiki>&bar{{!}}bat<nowiki><p></nowiki>|test2 = 
I'm so '''bold'''!}} '''Foo''' is a [[bar]].}} {{uncategorized}}");
                });
        });
        it('is safe to mutate template arguments', function() {
@@ -113,7 +135,9 @@
                return Parsoid.parse(text, { pdoc: true }).then(function(pdoc) {
                        var t = pdoc.filterTemplates()[0];
                        t.remove(1);
-                       String(pdoc).should.equal('{{echo||bar}}');
+                       return pdoc.toWikitext();
+               }).then(function(wt) {
+                       wt.should.equal('{{echo||bar}}');
                });
        });
        it('is safe to mutate template arguments (2)', function() {
@@ -124,7 +148,9 @@
                        var param2 = t.get(2);
                        param2.value = param1.value;
                        param1.value = '|';
-                       String(pdoc).should.equal('{{echo|{{!}}|foo}}');
+                       return pdoc.toWikitext();
+               }).then(function(wt) {
+                       wt.should.equal('{{echo|{{!}}|foo}}');
                });
        });
        it('filters and mutates headings', function() {
@@ -143,47 +169,77 @@
                        headings[0].title = '=0=';
                        headings[1].title = headings[2].title;
                        headings[3].level = 3;
-                       String(pdoc).should.equal('=<nowiki>=0=</nowiki>=\n== 
three ==\n=== three ===\n\n=== four ===\nbody\n');
+                       return pdoc.toWikitext();
+               }).then(function(wt) {
+                       wt.should.equal('=<nowiki>=0=</nowiki>=\n== three 
==\n=== three ===\n\n=== four ===\nbody\n');
                });
        });
        it('filters and mutates headings inside templates', function() {
                var text = "{{echo|1=\n= one =\n}}";
-               return Parsoid.parse(text, { pdoc: true }).then(function(pdoc) {
-                       var headings = pdoc.filterHeadings();
+               var pdoc, headings;
+               return Parsoid.parse(text, { pdoc: true }).then(function(_pdoc) 
{
+                       pdoc = _pdoc;
+                       headings = pdoc.filterHeadings();
                        headings.length.should.equal(1);
                        headings[0].level = 2;
-                       String(headings[0]).should.equal('== one ==\n');
-                       String(pdoc).should.equal('{{echo|1=\n== one ==\n}}');
+                       return headings[0].toWikitext();
+               }).then(function(wt) {
+                       wt.should.equal('== one ==\n');
+                       return pdoc.toWikitext();
+               }).then(function(wt) {
+                       wt.should.equal('{{echo|1=\n== one ==\n}}');
                        headings[0].title = 'two';
-                       String(headings[0]).should.equal('== two ==\n');
-                       String(pdoc).should.equal('{{echo|1=\n== two ==\n}}');
+                       return headings[0].toWikitext();
+               }).then(function(wt) {
+                       wt.should.equal('== two ==\n');
+                       return pdoc.toWikitext();
+               }).then(function(wt) {
+                       wt.should.equal('{{echo|1=\n== two ==\n}}');
                });
        });
        it('filters and mutates external links', function() {
                var text = "[http://example.com {{echo|link content}}]";
-               return Parsoid.parse(text, { pdoc: true }).then(function(pdoc) {
-                       var extlinks = pdoc.filterExtLinks();
+               var pdoc, extlinks;
+               return Parsoid.parse(text, { pdoc: true }).then(function(_pdoc) 
{
+                       pdoc = _pdoc;
+                       extlinks = pdoc.filterExtLinks();
                        extlinks.length.should.equal(1);
                        
String(extlinks[0].url).should.equal('http://example.com');
-                       String(extlinks[0].title).should.equal('{{echo|link 
content}}');
+                       return extlinks[0].title.toWikitext();
+               }).then(function(wt) {
+                       wt.should.equal('{{echo|link content}}');
                        extlinks[0].title = ']';
-                       String(pdoc).should.equal('[http://example.com 
<nowiki>]</nowiki>]\n');
+                       return pdoc.toWikitext();
+               }).then(function(wt) {
+                       wt.should.equal('[http://example.com 
<nowiki>]</nowiki>]\n');
                });
        });
        it('filters and mutates wiki links', function() {
                var text = "[[foo|1]] {{echo|[[bar|2]]}} [[{{echo|bat}}|3]]";
-               return Parsoid.parse(text, { pdoc: true }).then(function(pdoc) {
-                       var extlinks = pdoc.filterWikiLinks();
+               var pdoc, extlinks;
+               return Parsoid.parse(text, { pdoc: true }).then(function(_pdoc) 
{
+                       pdoc = _pdoc;
+                       extlinks = pdoc.filterWikiLinks();
                        extlinks.length.should.equal(3);
-                       String(extlinks[0].title).should.equal('Foo');
-                       String(extlinks[0].text).should.equal('1');
-                       String(extlinks[1].title).should.equal('Bar');
-                       String(extlinks[1].text).should.equal('2');
-                       String(extlinks[2].text).should.equal('3');
+                       return Promise.all([
+                               extlinks[0].title,
+                               extlinks[0].text.toWikitext(),
+                               extlinks[1].title,
+                               extlinks[1].text.toWikitext(),
+                               extlinks[2].text.toWikitext(),
+                       ]);
+               }).then(function(all) {
+                       all[0].should.equal('Foo');
+                       all[1].should.equal('1');
+                       all[2].should.equal('Bar');
+                       all[3].should.equal('2');
+                       all[4].should.equal('3');
                        extlinks[0].title = extlinks[0].text = 'foobar';
                        extlinks[1].text = 'A';
                        extlinks[2].text = 'B';
-                       String(pdoc).should.equal('[[foobar]] 
{{echo|[[bar|A]]}} [[{{echo|bat}}|B]]\n');
+                       return pdoc.toWikitext();
+               }).then(function(wt) {
+                       wt.should.equal('[[foobar]] {{echo|[[bar|A]]}} 
[[{{echo|bat}}|B]]\n');
                });
        });
        it('filters and mutates html entities', function() {
@@ -195,7 +251,9 @@
                        entities[1].normalized.should.equal('"');
                        entities[0].normalized = '<';
                        entities[1].normalized = '>';
-                       String(pdoc).should.equal('&#x3C;{{echo|&#x3E;}}\n');
+                       return pdoc.toWikitext();
+               }).then(function(wt) {
+                       wt.should.equal('&#x3C;{{echo|&#x3E;}}\n');
                });
        });
        it('filters and mutates comments', function() {
@@ -207,37 +265,53 @@
                        comments[1].contents.should.equal('bar');
                        comments[0].contents = '<!-- ha! -->';
                        comments[1].contents = '--';
-                       String(pdoc).should.equal('<!--<!-- ha! --&gt;--> 
{{echo|<!------>}}');
+                       return pdoc.toWikitext();
+               }).then(function(wt) {
+                       wt.should.equal('<!--<!-- ha! --&gt;--> 
{{echo|<!------>}}');
                });
        });
        it('filters and mutates images', function() {
                var text = '[[File:SomeFile1.jpg]] 
[[File:SomeFile2.jpg|thumb|caption]]';
-               return Parsoid.parse(text, { pdoc: true }).then(function(pdoc) {
-                       var media = pdoc.filterMedia();
+               var pdoc, media;
+               return Parsoid.parse(text, { pdoc: true }).then(function(_pdoc) 
{
+                       pdoc = _pdoc;
+                       media = pdoc.filterMedia();
                        media.length.should.equal(2);
                        media[0].should.have.property('caption', null);
-                       String(media[1].caption).should.equal('caption');
+                       return media[1].caption.toWikitext();
+               }).then(function(wt) {
+                       wt.should.equal('caption');
                        media[0].caption = '|';
                        media[1].caption = null;
-                       
String(pdoc).should.equal('[[File:SomeFile1.jpg|<nowiki>|</nowiki>]] 
[[File:SomeFile2.jpg|thumb]]');
+                       return pdoc.toWikitext();
+               }).then(function(wt) {
+                       
wt.should.equal('[[File:SomeFile1.jpg|<nowiki>|</nowiki>]] 
[[File:SomeFile2.jpg|thumb]]');
                        media[0].caption = null;
                        media[1].caption = '|';
-                       String(pdoc).should.equal('[[File:SomeFile1.jpg]] 
[[File:SomeFile2.jpg|thumb|<nowiki>|</nowiki>]]');
+                       return pdoc.toWikitext();
+               }).then(function(wt) {
+                       wt.should.equal('[[File:SomeFile1.jpg]] 
[[File:SomeFile2.jpg|thumb|<nowiki>|</nowiki>]]');
                });
        });
        it('filters and mutates text', function() {
                var text = 'foo {{echo|bar}}';
-               return Parsoid.parse(text, { pdoc: true }).then(function(pdoc) {
-                       var texts = pdoc.filterText({ recursive: false });
+               var pdoc, texts;
+               return Parsoid.parse(text, { pdoc: true }).then(function(_pdoc) 
{
+                       pdoc = _pdoc;
+                       texts = pdoc.filterText({ recursive: false });
                        texts.length.should.equal(1);
                        texts = pdoc.filterText({ recursive: true });
                        texts.length.should.equal(2);
                        texts[0].value.should.equal('foo ');
                        texts[1].value.should.equal('bar');
                        texts[0].value = 'FOO ';
-                       String(pdoc).should.equal('FOO {{echo|bar}}\n');
+                       return pdoc.toWikitext();
+               }).then(function(wt) {
+                       wt.should.equal('FOO {{echo|bar}}\n');
                        texts[1].value = 'BAR';
-                       String(pdoc).should.equal('FOO {{echo|BAR}}\n');
+                       return pdoc.toWikitext();
+               }).then(function(wt) {
+                       wt.should.equal('FOO {{echo|BAR}}\n');
                });
        });
        it.skip('filters and mutates text (2)', function() {
@@ -253,15 +327,19 @@
        });
        it('allows mutation using wikitext', function() {
                var text = '== heading ==';
-               return Parsoid.parse(text, { pdoc: true }).then(function(pdoc) {
-                       var headings = pdoc.filterHeadings();
+               var pdoc, headings;
+               return Parsoid.parse(text, { pdoc: true }).then(function(_pdoc) 
{
+                       pdoc = _pdoc;
+                       headings = pdoc.filterHeadings();
                        headings.length.should.equal(1);
                        // Note that even if the wikitext is unbalanced, the 
result
                        // will be balanced.  The bold face doesn't escape the 
heading!
-                       return Parsoid.PNodeList.fromWikitext(pdoc, 
"'''bold").then(function(pnl) {
-                               headings[0].title = pnl;
-                               String(pdoc).should.equal("== '''bold''' ==\n");
-                       });
+                       return Parsoid.PNodeList.fromWikitext(pdoc, "'''bold");
+               }).then(function(pnl) {
+                       headings[0].title = pnl;
+                       return pdoc.toWikitext();
+               }).then(function(wt) {
+                       wt.should.equal("== '''bold''' ==\n");
                });
        });
        it('allows iteration using length and get()', function() {

-- 
To view, visit https://gerrit.wikimedia.org/r/252886
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I33717f9261885bd121aef27360602fe8ebbc8ccb
Gerrit-PatchSet: 14
Gerrit-Project: mediawiki/services/parsoid
Gerrit-Branch: master
Gerrit-Owner: Arlolra <abrea...@wikimedia.org>
Gerrit-Reviewer: Arlolra <abrea...@wikimedia.org>
Gerrit-Reviewer: Cscott <canan...@wikimedia.org>
Gerrit-Reviewer: Subramanya Sastry <ssas...@wikimedia.org>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to