diff --git a/test/badges.js b/test/badges.js new file mode 100644 index 0000000..9183031 --- /dev/null +++ b/test/badges.js @@ -0,0 +1,23 @@ +/* globals before, describe, it */ + +var assert = require('assert') +var marky = require('..') +var fixtures = require('./fixtures') + +describe('badges', function () { + var $ + + before(function () { + $ = marky(fixtures.badges) + }) + + it('adds a badge class to img tags containing badge images', function () { + assert($('img').length) + assert.equal($('img').length, $('img.badge').length) + }) + + it('adds a badge-only class to p tags containing nothing more than a badge', function () { + assert.equal($('p:not(.badge-only)').length, 2) + assert.equal($('p.badge-only').length, $('p').length - 2) + }) +}) diff --git a/test/cdn.js b/test/cdn.js new file mode 100644 index 0000000..fbd78ac --- /dev/null +++ b/test/cdn.js @@ -0,0 +1,73 @@ +/* globals before, describe, it */ + +var assert = require('assert') +var marky = require('..') +var fixtures = require('./fixtures') + +describe('cdn', function () { + describe('when serveImagesWithCDN is true', function () { + var $ + var options = { + package: {name: 'foo', version: '1.0.0'}, + serveImagesWithCDN: true + } + + before(function () { + $ = marky(fixtures.basic, options) + }) + + it('replaces relative img URLs with npm CDN URLs', function () { + assert(~fixtures.basic.indexOf('![](relative.png)')) + assert($("img[src='https://cdn.npm.im/foo@1.0.0/relative.png']").length) + }) + + it('replaces slashy relative img URLs with npm CDN URLs', function () { + assert(~fixtures.basic.indexOf('![](/slashy/deep.png)')) + assert($("img[src='https://cdn.npm.im/foo@1.0.0/slashy/deep.png']").length) + }) + + it('leaves protocol relative URLs alone', function () { + assert(~fixtures.basic.indexOf('![](//protocollie.com/woof.png)')) + assert($("img[src='//protocollie.com/woof.png']").length) + }) + + it('leaves HTTPS URLs alone', function () { + assert(~fixtures.basic.indexOf('![](https://secure.com/good.png)')) + assert($("img[src='https://secure.com/good.png']").length) + }) + }) + + describe('when serveImagesWithCDN is false (default)', function () { + var $ + var options = { + package: { + name: 'foo', + version: '1.0.0' + } + } + + before(function () { + $ = marky(fixtures.basic, options) + }) + + it('leaves relative img alone', function () { + assert(~fixtures.basic.indexOf('![](relative.png)')) + assert($("img[src='relative.png']").length) + }) + + it('leaves slashy relative img URLs alone', function () { + assert(~fixtures.basic.indexOf('![](/slashy/deep.png)')) + assert($("img[src='/slashy/deep.png']").length) + }) + + it('leaves protocol relative URLs alone', function () { + assert(~fixtures.basic.indexOf('![](//protocollie.com/woof.png)')) + assert($("img[src='//protocollie.com/woof.png']").length) + }) + + it('leaves HTTPS URLs alone', function () { + assert(~fixtures.basic.indexOf('![](https://secure.com/good.png)')) + assert($("img[src='https://secure.com/good.png']").length) + }) + }) +}) diff --git a/test/fixtures.js b/test/fixtures.js index 6c7c674..86958f2 100644 --- a/test/fixtures.js +++ b/test/fixtures.js @@ -1,6 +1,7 @@ var fs = require('fs') var path = require('path') var glob = require('glob') +var pkg = require('../package.json') var fixtures = { dependencies: [], // our dependencies and devDependencies @@ -16,8 +17,8 @@ fs.readdirSync(__dirname + '/fixtures').forEach(function (file) { }) // Read in dependencies' and devDependencies' readmes -fixtures.dependencies = Object.keys(require('../package.json').devDependencies) - .concat(Object.keys(require('../package.json').dependencies)) +fixtures.dependencies = Object.keys(pkg.devDependencies) + .concat(Object.keys(pkg.dependencies)) .sort() fixtures.dependencies.forEach(function (name) { var modulePath = path.resolve('node_modules', name) diff --git a/test/github.js b/test/github.js new file mode 100644 index 0000000..372cb06 --- /dev/null +++ b/test/github.js @@ -0,0 +1,6 @@ +/* globals describe */ + +describe('github', function () { + require('./repo-github') + require('./repo-other') +}) diff --git a/test/gravatar.js b/test/gravatar.js new file mode 100644 index 0000000..6008c70 --- /dev/null +++ b/test/gravatar.js @@ -0,0 +1,29 @@ +/* globals before, describe, it */ + +var assert = require('assert') +var marky = require('..') +var fixtures = require('./fixtures') + +describe('gravatar', function () { + var $ + + before(function () { + $ = marky(fixtures.gravatar) + }) + + it('replaces insecure gravatar img src URLs with secure HTTPS URLs', function () { + assert(~fixtures.gravatar.indexOf('http://gravatar.com/avatar/123?s=50&d=retro')) + assert.equal($('img').length, 3) + assert.equal($('img').eq(0).attr('src'), 'https://secure.gravatar.com/avatar/123?s=50&d=retro') + }) + + it('leaves secure gravatar URLs untouched', function () { + assert(~fixtures.gravatar.indexOf('https://secure.gravatar.com/avatar/456?s=50&d=retro')) + assert.equal($('img').eq(1).attr('src'), 'https://secure.gravatar.com/avatar/456?s=50&d=retro') + }) + + it('leaves non-gravtar URLs untouched', function () { + assert(~fixtures.gravatar.indexOf('http://not-gravatar.com/foo')) + assert.equal($('img').eq(2).attr('src'), 'http://not-gravatar.com/foo') + }) +}) diff --git a/test/headings.js b/test/headings.js new file mode 100644 index 0000000..55ac429 --- /dev/null +++ b/test/headings.js @@ -0,0 +1,97 @@ +/* globals before, describe, it */ + +var assert = require('assert') +var marky = require('..') +var fixtures = require('./fixtures') + +describe('headings', function () { + var $ + + before(function () { + $ = marky(fixtures.dirty) + }) + + it('injects hashy anchor tags into headings that have DOM ids', function () { + assert(~fixtures.dirty.indexOf('# h1')) + assert($("h1 a[href='#h1']").length) + }) + + it('adds deep-link class to modified headings', function () { + assert(~fixtures.dirty.indexOf('# h1')) + assert($("h1.deep-link a[href='#h1']").length) + }) + + it("doesn't inject anchor tags into headings that already contain anchors", function () { + assert(~fixtures.dirty.indexOf('### [h3](/already/linky)')) + assert($("h3 a[href='/already/linky']").length) + }) + + it('applies a prefix to generated DOM ids by default', function () { + assert(~fixtures.dirty.indexOf('## h2')) + assert.equal($('h2#user-content-h2').length, 1) + }) + + it('allows id prefixes to be disabled with prefixHeadingIds', function () { + assert(~fixtures.dirty.indexOf('#### This is a TEST')) + $ = marky(fixtures.dirty, {prefixHeadingIds: false}) + assert.equal($('h4#this-is-a-test').length, 1) + }) + + it('allows a dash in generated DOM ids just like GitHub', function () { + assert(~fixtures.github.indexOf('### heading with a - dash')) + $ = marky(fixtures.github) + assert.equal($('h3#heading-with-a---dash a').length, 1) + }) + + it('allows a trailing dash in generated DOM ids just like GitHub', function () { + assert(~fixtures.github.indexOf('### heading with a trailing dash -')) + $ = marky(fixtures.github) + assert.equal($('h3#heading-with-a-trailing-dash-- a').length, 1) + }) + + it('allows underscores in generated DOM ids like GitHub', function () { + assert(~fixtures.github.indexOf('### heading with an _ underscore')) + $ = marky(fixtures.github) + assert.equal($('h3#heading-with-an-_-underscore a').length, 1) + }) + + it('filters periods in generated DOM ids like GitHub', function () { + assert(~fixtures.github.indexOf('### heading with a period.txt')) + $ = marky(fixtures.github) + assert.equal($('h3#heading-with-a-periodtxt').length, 1) + }) + + it('allows two spaces even after filtering like GitHub', function () { + assert(~fixtures.github.indexOf('### exchange.bind_headers(exchange, routing [, bindCallback])')) + $ = marky(fixtures.github) + assert.equal($('h3#exchangebind_headersexchange-routing--bindcallback').length, 1) + }) + + it('add suffix to duplicate generated DOM ids like GitHub', function () { + assert(~fixtures.github.indexOf('### duplicate')) + assert(~fixtures.github.indexOf('### duplicate(')) + assert(~fixtures.github.indexOf('### duplicate)')) + $ = marky(fixtures.github) + assert.equal($('h3#duplicate a').length, 1) + assert.equal($('h3#duplicate-1 a').length, 1) + assert.equal($('h3#duplicate-2 a').length, 1) + }) + + it('encodes innerHTML and removes angle brackets before generating ids', function () { + assert(~fixtures.payform.indexOf('## Browser `` Helpers')) + $ = marky(fixtures.payform, {prefixHeadingIds: false}) + assert.equal($('h2#browser-input-helpers a').length, 1) + assert.equal($('h2#browser-input-helpers a').html(), 'Browser <input> Helpers') + }) + + it('properly handles headings lacking a space between the leading #(s) and heading text', function () { + assert(~fixtures.lazyheading.indexOf('#lazy heading')) + $ = marky(fixtures.lazyheading, {prefixHeadingIds: false}) + assert.equal($('h1#lazy-heading-1').length, 1) + assert.equal($('h2#lazy-heading-2').length, 1) + assert.equal($('h3#lazy-heading-3').length, 1) + assert.equal($('h4#lazy-heading-4').length, 1) + assert.equal($('h5#lazy-heading-5').length, 1) + assert.equal($('h6#lazy-heading-6').length, 1) + }) +}) diff --git a/test/index.js b/test/index.js index 5b6b0c0..bf3828e 100644 --- a/test/index.js +++ b/test/index.js @@ -1,696 +1,12 @@ -/* globals before, describe, it */ - -var assert = require('assert') -var path = require('path') -var fixtures = require('./fixtures.js') -var marky = require('..') - -describe('marky-markdown', function () { - it('is a function', function () { - assert(marky) - assert(typeof marky === 'function') - }) - - it('accepts a markdown string and returns a cheerio DOM object', function () { - var $ = marky('hello, world') - assert($.html) - assert($._root) - assert($._options) - assert(~$.html().indexOf('

hello, world

\n')) - }) - - it('throws an error if first argument is not a string', function () { - assert.throws( - function () { marky(null) }, - /first argument must be a string/ - ) - }) -}) - -describe('markdown processing and syntax highlighting', function () { - var $ - before(function () { - $ = marky(fixtures.basic, {highlightSyntax: true}) - }) - - it('preserves query parameters in URLs when making them into links', function () { - assert(~fixtures.basic.indexOf('watch?v=dQw4w9WgXcQ')) - assert.equal($("a[href*='youtube.com']").attr('href'), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ') - }) - - it('converts github flavored fencing to code blocks', function () { - assert(~fixtures.basic.indexOf('```js')) - assert($('code').length) - }) - - it('adds js class to javascript blocks', function () { - assert(~fixtures.basic.indexOf('```js')) - assert($('code.js').length) - }) - - it('adds sh class to shell blocks', function () { - assert(~fixtures.basic.indexOf('```sh')) - assert($('code.sh').length) - }) - - it('adds coffeescript class to coffee blocks', function () { - assert(~fixtures.basic.indexOf('```coffee')) - assert($('code.coffeescript').length) - }) - - it('adds diff class to diff blocks', function () { - assert(~fixtures.basic.indexOf('```diff')) - assert($('code.diff').length) - }) - - it('adds highlight class to all blocks', function () { - assert.equal($('code').length, $('code.highlight').length) - }) - - it('applies inline syntax highlighting classes to javascript', function () { - assert($('.js.modifier').length) - assert($('.js.function').length) - }) - - it('applies inline syntax highlighting classes to shell', function () { - assert($('.shell.builtin').length) - }) - - it('applies inline syntax highlighting classes to coffeescript', function () { - assert($('.coffee.begin').length) - }) - - it('applies inline syntax highlighting classes to diffs', function () { - assert($('.diff.inserted').length) - assert($('.diff.deleted').length) - }) - - it('does not encode entities within code blocks', function () { - assert(~fixtures.enterprise.indexOf('"name": "@myco/anypackage"')) - var $ = marky(fixtures.enterprise) - assert(!~$.html().indexOf('quot')) - assert(~$.html().indexOf('"')) - }) - - it('linkifies fully-qualified URLs', function () { - assert(~fixtures['maintenance-modules'].indexOf('- https://gist.github.com/sindresorhus/8435329')) - var $ = marky(fixtures['maintenance-modules']) - assert($("a[href='https://gist.github.com/sindresorhus/8435329']").length) - }) - - it('replaces markdown syntax for emoji with unicode for the emoji', function () { - assert(~fixtures.github.indexOf(':sparkles:')) - var $ = marky(fixtures.github) - assert($.html().indexOf('✨')) - }) - - it('does not convert text emoticons to unicode', function () { - assert(~fixtures.github.indexOf(':)')) - var $ = marky(fixtures.github) - assert(~$.html().indexOf(':)')) - }) -}) - -describe('sanitize', function () { - var $ - - before(function () { - $ = marky(fixtures.dirty) - }) - - it('removes script tags', function () { - assert(~fixtures.dirty.indexOf(' strikethrough element', function () { - assert(~fixtures.dirty.indexOf('~~orange~~')) - assert.equal($('s').text(), 'orange') - }) - - it('disallows iframes from sources other than youtube', function () { - var $ = marky(fixtures.basic) - assert(~fixtures.basic.indexOf('