From c8e254ad2caa78f4fd900085ad2004878c0b5671 Mon Sep 17 00:00:00 2001 From: Mike Pennisi Date: Sat, 21 Apr 2018 20:00:48 -0400 Subject: [PATCH] Formally test deprecated APIs Methods named `load`, `html`, `xml`, and `text` are defined in many locations: Today, Cheerio defines multiple versions of methods named `load`, `html`, `xml`, `text`, and `parseHTML`. These alternate versions may be defined in up to three distinct parts of the API: - exported by the Cheerio module - as static methods of the "loaded" Cheerio factory function - as instance methods of the "loaded" Cheerio factory function Some of these are surperfluous, and because some unecessarily conflict with idiomatic jQuery coding patterns, they have been designated for future removal [1]. Add tests for the deprecated methods in order to avoid regressions prior to their removal. Insert comments to delineate the methods which are endorsed and which have been deprecated. For the latter group of methods, include recommendation for the preferred alternatives. [1] https://github.com/cheeriojs/cheerio/issues/1122 --- test/api/utils.js | 68 ++++++++++++++----------- test/cheerio.js | 125 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 164 insertions(+), 29 deletions(-) diff --git a/test/api/utils.js b/test/api/utils.js index dd00939b51..28c0ab7d55 100644 --- a/test/api/utils.js +++ b/test/api/utils.js @@ -21,33 +21,24 @@ describe('cheerio', function() { var $elem = cheerio('foo').html(''); expect(cheerio.html($elem)).to.equal(''); }); - - it('() : of empty cheerio object should return null', function() { - expect(cheerio().html()).to.be(null); - }); - - it('(selector) : should return the outerHTML of the selected element', function() { - var $ = cheerio.load(fixtures.fruits); - expect($.html('.pear')).to.equal('
  • Pear
  • '); - }); }); describe('.text', function() { it('(cheerio object) : should return the text contents of the specified elements', function() { var $ = cheerio.load('This is content.'); - expect($.text($('a'))).to.equal('This is content.'); + expect(cheerio.text($('a'))).to.equal('This is content.'); }); it('(cheerio object) : should omit comment nodes', function() { var $ = cheerio.load('This is not a comment.'); - expect($.text($('a'))).to.equal('This is not a comment.'); + expect(cheerio.text($('a'))).to.equal('This is not a comment.'); }); it('(cheerio object) : should include text contents of children recursively', function() { var $ = cheerio.load( 'This is
    a child with another child and not a comment followed by one last child and some final
    text.
    ' ); - expect($.text($('a'))).to.equal( + expect(cheerio.text($('a'))).to.equal( 'This is a child with another child and not a comment followed by one last child and some final text.' ); }); @@ -56,14 +47,14 @@ describe('cheerio', function() { var $ = cheerio.load( 'This is
    a child with another child and not a comment followed by one last child and some final
    text.
    ' ); - expect($.text()).to.equal( + expect(cheerio.text($.root())).to.equal( 'This is a child with another child and not a comment followed by one last child and some final text.' ); }); it('(cheerio object) : should omit script tags', function() { var $ = cheerio.load(''); - expect($.text()).to.equal(''); + expect(cheerio.text($.root())).to.equal(''); }); it('(cheerio object) : should omit style tags', function() { @@ -77,7 +68,7 @@ describe('cheerio', function() { var $ = cheerio.load( 'Welcome
    Hello, testing text function,
    End of messege' ); - expect($.text()).to.equal( + expect(cheerio.text($.root())).to.equal( 'Welcome Hello, testing text function,End of messege' ); }); @@ -155,21 +146,23 @@ describe('cheerio', function() { }); describe('.parseHTML', function() { + var $ = cheerio.load(''); + it('() : returns null', function() { - expect(cheerio.parseHTML()).to.equal(null); + expect($.parseHTML()).to.equal(null); }); it('(null) : returns null', function() { - expect(cheerio.parseHTML(null)).to.equal(null); + expect($.parseHTML(null)).to.equal(null); }); it('("") : returns null', function() { - expect(cheerio.parseHTML('')).to.equal(null); + expect($.parseHTML('')).to.equal(null); }); it('(largeHtmlString) : parses large HTML strings', function() { var html = new Array(10).join('
    '); - var nodes = cheerio.parseHTML(html); + var nodes = $.parseHTML(html); expect(nodes.length).to.be.greaterThan(4); expect(nodes).to.be.an('array'); @@ -177,48 +170,48 @@ describe('cheerio', function() { it('("'; - expect(cheerio.parseHTML(html)).to.have.length(0); + expect($.parseHTML(html)).to.have.length(0); }); it('("'; - expect(cheerio.parseHTML(html, true)[0].tagName).to.match(/script/i); + expect($.parseHTML(html, true)[0].tagName).to.match(/script/i); }); it('("scriptAndNonScript) : preserves non-script nodes', function() { var html = '
    '; - expect(cheerio.parseHTML(html)[0].tagName).to.match(/div/i); + expect($.parseHTML(html)[0].tagName).to.match(/div/i); }); it('(scriptAndNonScript, true) : Preserves script position', function() { var html = '
    '; - expect(cheerio.parseHTML(html, true)[0].tagName).to.match(/script/i); + expect($.parseHTML(html, true)[0].tagName).to.match(/script/i); }); it('(text) : returns a text node', function() { - expect(cheerio.parseHTML('text')[0].type).to.be('text'); + expect($.parseHTML('text')[0].type).to.be('text'); }); it('(\\ttext) : preserves leading whitespace', function() { - expect(cheerio.parseHTML('\t
    ')[0].data).to.equal('\t'); + expect($.parseHTML('\t
    ')[0].data).to.equal('\t'); }); it('( text) : Leading spaces are treated as text nodes', function() { - expect(cheerio.parseHTML('
    ')[0].type).to.be('text'); + expect($.parseHTML('
    ')[0].type).to.be('text'); }); it('(html) : should preserve content', function() { var html = '
    test div
    '; - expect(cheerio(cheerio.parseHTML(html)[0]).html()).to.equal('test div'); + expect(cheerio($.parseHTML(html)[0]).html()).to.equal('test div'); }); it('(malformedHtml) : should not break', function() { - expect(cheerio.parseHTML('')).to.have.length(1); + expect($.parseHTML('')).to.have.length(1); }); it('(garbageInput) : should not cause an error', function() { expect( - cheerio.parseHTML('<#if>

    This is a test.

    <#/if>') || true + $.parseHTML('<#if>

    This is a test.

    <#/if>') || true ).to.be.ok(); }); @@ -232,6 +225,23 @@ describe('cheerio', function() { }); }); + /** + * The `.parseHTML` method exported by the Cheerio module is deprecated. + * + * In order to promote consistency with the jQuery library, users are + * encouraged to instead use the static method of the same name as it is + * defined on the "loaded" Cheerio factory function. For example: + * + * var $ = cheerio.load(''); + * $.parseHTML('markup'); + */ + describe('.parseHTML - deprecated API', function() { + it('(html) : should preserve content', function() { + var html = '
    test div
    '; + expect(cheerio(cheerio.parseHTML(html)[0]).html()).to.equal('test div'); + }); + }); + describe('.contains', function() { var $; diff --git a/test/cheerio.js b/test/cheerio.js index aef5b21712..a08d8281cf 100644 --- a/test/cheerio.js +++ b/test/cheerio.js @@ -330,6 +330,117 @@ describe('cheerio', function() { }); }); + /** + * The `.html` static method defined on the "loaded" Cheerio factory function + * is deprecated. + * + * In order to promote consistency with the jQuery library, users are + * encouraged to instead use the instance method of the same name. For + * example: + * + * var $ = cheerio.load('

    Hello, world.

    '); + * $('h1').text(); // '

    Hello, world.' + * + * To render the markup of an entire document, invoke the `html` function + * exported by the Cheerio module with a "root" selection, e.g. + * + * cheerio.html($.root()); // '

    Hello, world.

    ' + */ + describe('.html - deprecated API', function() { + it('() : of empty cheerio object should return null', function() { + // Note: the direct invocation of the Cheerio constructor function is + // also deprecated. + var $ = cheerio(); + expect($.html()).to.be(null); + }); + + it('(selector) : should return the outerHTML of the selected element', function() { + var $ = cheerio.load(fixtures.fruits); + expect($.html('.pear')).to.equal('
  • Pear
  • '); + }); + }); + + /** + * The `.xml` static method defined on the "loaded" Cheerio factory function + * is deprecated. Users are encouraged to instead use the `xml` function + * exported by the Cheerio module. For example: + * + * cheerio.xml($.root()); + */ + describe('.xml - deprecated API', function() { + it('() : renders XML', function() { + var $ = cheerio.load('', { xmlMode: true }); + expect($.xml()).to.equal(''); + }); + }); + + /** + * The `.text` static method defined on the "loaded" Cheerio factory function + * is deprecated. + * + * In order to promote consistency with the jQuery library, users are + * encouraged to instead use the instance method of the same name. For + * example: + * + * var $ = cheerio.load('

    Hello, world.

    '); + * $('h1').text(); // 'Hello, world.' + * + * To render the text content of an entire document, invoke the `text` + * function exported by the Cheerio module with a "root" selection, e.g. + * + * cheerio.text($.root()); // 'Hello, world.' + */ + describe('.text - deprecated API', function() { + it('(cheerio object) : should return the text contents of the specified elements', function() { + var $ = cheerio.load('This is content.'); + expect($.text($('a'))).to.equal('This is content.'); + }); + + it('(cheerio object) : should omit comment nodes', function() { + var $ = cheerio.load('This is not a comment.'); + expect($.text($('a'))).to.equal('This is not a comment.'); + }); + + it('(cheerio object) : should include text contents of children recursively', function() { + var $ = cheerio.load( + 'This is
    a child with another child and not a comment followed by one last child and some final
    text.
    ' + ); + expect($.text($('a'))).to.equal( + 'This is a child with another child and not a comment followed by one last child and some final text.' + ); + }); + + it('() : should return the rendered text content of the root', function() { + var $ = cheerio.load( + 'This is
    a child with another child and not a comment followed by one last child and some final
    text.
    ' + ); + expect($.text()).to.equal( + 'This is a child with another child and not a comment followed by one last child and some final text.' + ); + }); + + it('(cheerio object) : should omit script tags', function() { + var $ = cheerio.load(''); + expect($.text()).to.equal(''); + }); + + it('(cheerio object) : should omit style tags', function() { + var $ = cheerio.load( + '' + ); + expect($.text()).to.equal(''); + }); + + it('(cheerio object) : should include text contents of children omiting style and script tags', function() { + var $ = cheerio.load( + 'Welcome
    Hello, testing text function,
    End of messege' + ); + expect($.text()).to.equal( + 'Welcome Hello, testing text function,End of messege' + ); + }); + }); + describe('.load', function() { it('should generate selections as proper instances', function() { var $ = cheerio.load(fruits); @@ -346,6 +457,20 @@ describe('cheerio', function() { expect(lis).to.have.length(3); }); + /** + * The `.load` static method defined on the "loaded" Cheerio factory + * function is deprecated. Users are encouraged to instead use the `load` + * function exported by the Cheerio module. For example: + * + * var $ = cheerio.load('

    Hello, world.

    '); + */ + it('should be available as a static method on the "loaded" factory function (deprecated API)', function() { + var $1 = cheerio.load(fruits); + var $2 = $1.load('

    Some text.

    '); + + expect($2('a')).to.have.length(1); + }); + it('should allow loading a pre-parsed DOM', function() { var dom = htmlparser2.parseDOM(food), $ = cheerio.load(dom);