test: implement karma and browserstack tests

issues/907-white-space-in-bold-and-italic-causes-problems
Estevão Soares dos Santos 2022-03-27 00:05:30 +00:00
parent db571fbaac
commit 9a3e714b2c
19 changed files with 2285 additions and 206 deletions

View File

@ -1,4 +1,7 @@
{ {
"env": {
"es6": true
},
"rules": { "rules": {
"indent": [2, 2, {"SwitchCase": 1, "VariableDeclarator": 2}], "indent": [2, 2, {"SwitchCase": 1, "VariableDeclarator": 2}],
"curly": [2, "all"], "curly": [2, "all"],

48
.github/workflows/browserstack.yml vendored Normal file
View File

@ -0,0 +1,48 @@
name: 'BrowserStack Test'
on:
push:
branches: [ master, develop ]
pull_request:
branches: [ master, develop ]
jobs:
ubuntu-job:
name: 'BrowserStack Test on Ubuntu'
runs-on: ubuntu-latest
steps:
- name: 'BrowserStack Env Setup' # Invokes the setup-env action
uses: browserstack/github-actions/setup-env@master
with:
username: ${{ secrets.BROWSERSTACK_USERNAME }}
access-key: ${{ secrets.BROWSERSTACK_ACCESSKEY }}
- name: 'BrowserStack Local Tunnel Setup' # Invokes the setup-local action
uses: browserstack/github-actions/setup-local@master
with:
local-testing: start
local-identifier: random
# The next 3 steps are for building the web application to be tested and starting the web server on the runner environment
- name: 'Checkout the repository'
uses: actions/checkout@v2
- name: '🚚 Upgrade NPM'
run: npm install -g npm
- name: 'Use Node.js 17.x'
uses: actions/setup-node@v2
with:
node-version: 17.x
cache: 'npm'
- name: 'Concatenate src files for testing'
run: grunt concat:test
- name: 'Running test on BrowserStack with Karma'
run: karma start karma.browserstack.js
- name: 'BrowserStackLocal Stop' # Terminating the BrowserStackLocal tunnel connection
uses: browserstack/github-actions/setup-local@master
with:
local-testing: stop

1
.gitignore vendored
View File

@ -4,3 +4,4 @@
node_modules node_modules
npm-debug.log npm-debug.log
/*.test.* /*.test.*
*.log

View File

@ -3,3 +3,4 @@ dist/**/*.js
build/**/*.js build/**/*.js
src/options.js src/options.js
bin/* bin/*
/karma.browserstack.js

View File

@ -19,7 +19,6 @@
"smarttabs": true, "smarttabs": true,
"onevar": true, "onevar": true,
"globals": { "globals": {
"angular": true,
"module": true, "module": true,
"define": true, "define": true,
"window": true, "window": true,

View File

@ -8,6 +8,16 @@ module.exports = function (grunt) {
require('quiet-grunt'); require('quiet-grunt');
} }
/**
* Load common tasks for legacy and normal tests
*/
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-mocha-test');
grunt.loadNpmTasks('grunt-endline');
grunt.loadNpmTasks('grunt-contrib-jshint');
// Project configuration. // Project configuration.
var config = { var config = {
pkg: grunt.file.readJSON('package.json'), pkg: grunt.file.readJSON('package.json'),
@ -124,40 +134,40 @@ module.exports = function (grunt) {
} }
}, },
simplemocha: { mochaTest: {
functional: { functional: {
src: 'test/functional/**/*.js', src: 'test/functional/**/*.js',
options: { options: {
globals: ['should'],
timeout: 3000, timeout: 3000,
ignoreLeaks: true, ignoreLeaks: true,
reporter: 'spec' reporter: 'spec',
require: ['test/bootstrap.js']
} }
}, },
unit: { unit: {
src: 'test/unit/**/*.js', src: 'test/unit/**/*.js',
options: { options: {
globals: ['should'],
timeout: 3000, timeout: 3000,
ignoreLeaks: true, ignoreLeaks: true,
reporter: 'spec' reporter: 'spec',
require: ['test/bootstrap.js']
} }
}, },
single: { single: {
options: { options: {
globals: ['should'],
timeout: 3000, timeout: 3000,
ignoreLeaks: false, ignoreLeaks: false,
reporter: 'spec' reporter: 'spec',
require: ['test/bootstrap.js']
} }
}, },
cli: { cli: {
src: 'test/unit/cli.js', src: 'test/unit/cli.js',
options: { options: {
globals: ['should'],
timeout: 3000, timeout: 3000,
ignoreLeaks: false, ignoreLeaks: false,
reporter: 'spec' reporter: 'spec',
require: ['test/bootstrap.js']
} }
} }
} }
@ -165,16 +175,6 @@ module.exports = function (grunt) {
grunt.initConfig(config); grunt.initConfig(config);
/**
* Load common tasks for legacy and normal tests
*/
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-simple-mocha');
grunt.loadNpmTasks('grunt-endline');
grunt.loadNpmTasks('grunt-contrib-jshint');
/** /**
* Generate Changelog * Generate Changelog
*/ */
@ -210,23 +210,23 @@ module.exports = function (grunt) {
grunt.registerTask('single-test', function (file) { grunt.registerTask('single-test', function (file) {
'use strict'; 'use strict';
grunt.config.merge({ grunt.config.merge({
simplemocha: { mochaTest: {
single: { single: {
src: file src: file
} }
} }
}); });
grunt.task.run(['lint', 'concat:test', 'simplemocha:single', 'clean']); grunt.task.run(['lint', 'concat:test', 'mochaTest:single', 'clean']);
}); });
/** /**
* Tasks * Tasks
*/ */
grunt.registerTask('test', ['clean', 'lint', 'concat:test', 'simplemocha:unit', 'simplemocha:functional', 'clean']); grunt.registerTask('test', ['clean', 'lint', 'concat:test', 'mochaTest:unit', 'mochaTest:functional', 'clean']);
grunt.registerTask('test-functional', ['concat:test', 'simplemocha:functional', 'clean']); grunt.registerTask('test-functional', ['concat:test', 'mochaTest:functional', 'clean']);
grunt.registerTask('test-unit', ['concat:test', 'simplemocha:unit', 'clean']); grunt.registerTask('test-unit', ['concat:test', 'mochaTest:unit', 'clean']);
grunt.registerTask('test-cli', ['clean', 'lint', 'concat:test', 'simplemocha:cli', 'clean']); grunt.registerTask('test-cli', ['clean', 'lint', 'concat:test', 'mochaTest:cli', 'clean']);
grunt.registerTask('performance', ['concat:test', 'performancejs', 'clean']); grunt.registerTask('performance', ['concat:test', 'performancejs', 'clean']);
grunt.registerTask('build', ['test', 'concat:dist', 'concat:cli', 'uglify:dist', 'uglify:cli', 'endline']); grunt.registerTask('build', ['test', 'concat:dist', 'concat:cli', 'uglify:dist', 'uglify:cli', 'endline']);

View File

@ -101,12 +101,12 @@
## CLI ## CLI
- [ ] Refactor the CLI - [ ] Refactor the CLI
- [ ] **#381**: *Support for src and dst directories in showdown cli* - [ ] **#381**: *Support for src and dst directories in showdown cli*
- [ ] **#584**: *Fails to read from stdin* - [X] **#584**: *Fails to read from stdin*
- [ ] **#554**: *CLI not working with jsdom v10* - [X] **#554**: *CLI not working with jsdom v10*
## Other stuff ## Other stuff
- [X] Regexp rewrite for more performance oompf - [X] Regexp rewrite for more performance oompf
- [ ] Full unit testing - [X] Full unit testing
- [ ] Better error reporting - [ ] Better error reporting
## Stuff that probably won't make it to v2.0 ## Stuff that probably won't make it to v2.0
@ -138,3 +138,9 @@ This should address:
- [ ] Options - [ ] Options
- [ ] Extensions (and the new event system) - [ ] Extensions (and the new event system)
- [ ] Cookbook (with stuff for backwards compatibility, specially regarding removed options) - [ ] Cookbook (with stuff for backwards compatibility, specially regarding removed options)
## Browser Testing
- [X] Implement unit tests in Karma
- [ ] Implement functional tests in Karma
- [ ] Integrate with browserstack

64
karma.browserstack.js Normal file
View File

@ -0,0 +1,64 @@
module.exports = function (config) {
config.set({
// global config of your BrowserStack account
browserStack: {
username: process.env.BROWSERSTACK_USERNAME,
accessKey: process.env.BROWSERSTACK_ACCESSKEY
},
// define browsers
customLaunchers: {
bstack_chrome_windows: {
base: 'BrowserStack',
browser: 'chrome',
browser_version: '72.0',
os: 'Windows',
os_version: '10'
},
bstack_firefox_windows: {
base: 'BrowserStack',
browser: 'firefox',
browser_version: '98.0',
os: 'Windows',
os_version: '10'
},
//dropped support for IE 10
bstack_ie10_windows: {
base: 'BrowserStack',
browser: 'ie',
browser_version: '10',
os: 'Windows',
os_version: '7'
},
//dropped support for IE 10
bstack_ie11_windows: {
base: 'BrowserStack',
browser: 'ie',
browser_version: '11',
os: 'Windows',
os_version: '10'
},
bstack_iphoneX: {
base: 'BrowserStack',
browser: 'safari',
device: 'iPhone X',
os: 'ios',
real_mobile: true,
os_version: '11.0'
}
},
browsers: ['bstack_chrome_windows', 'bstack_firefox_windows', 'bstack_ie11_windows', 'bstack_iphoneX'],
frameworks: ['mocha', 'chai'],
reporters: ['dots', 'BrowserStack'],
files: [
{ pattern: '.build/showdown.js'},
{ pattern: 'src/options.js'},
// tests
{ pattern: 'test/unit/showdown*.js' },
{ pattern: 'test/functional/showdown*.js' },
],
singleRun: true,
concurrency: Infinity
});
};

36
karma.conf.js Normal file
View File

@ -0,0 +1,36 @@
module.exports = function (config) {
config.set({
client: {
captureConsole: true
},
browserConsoleLogOptions: {
level: 'log',
format: '%b %T: %m',
terminal: true
},
logLevel: config.LOG_LOG,
frameworks: ['mocha', 'chai'],
files: [
{ pattern: '.build/showdown.js'},
{ pattern: 'src/options.js'},
// tests
{ pattern: 'test/unit/showdown*.js' },
{ pattern: 'test/functional/showdown*.js' },
],
reporters: ['progress'],
port: 9876, // karma web server port
colors: true,
browsers: ['ChromeHeadless', 'FirefoxHeadless', 'jsdom'],
autoWatch: false,
singleRun: true, // Karma captures browsers, runs the tests and exits
//concurrency: Infinity,
customLaunchers: {
'FirefoxHeadless': {
base: 'Firefox',
flags: [
'-headless',
]
}
},
});
};

2053
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -58,16 +58,27 @@
"grunt-conventional-github-releaser": "^1.0.0", "grunt-conventional-github-releaser": "^1.0.0",
"grunt-endline": "^0.7.0", "grunt-endline": "^0.7.0",
"grunt-eslint": "^24.0.0", "grunt-eslint": "^24.0.0",
"grunt-mocha-test": "^0.13.3",
"grunt-simple-mocha": "^0.4.0", "grunt-simple-mocha": "^0.4.0",
"karma": "^6.3.17",
"karma-browserstack-launcher": "^1.6.0",
"karma-chai": "^0.1.0",
"karma-chrome-launcher": "^3.1.1",
"karma-firefox-launcher": "^2.1.2",
"karma-jsdom-launcher": "^12.0.0",
"karma-mocha": "^2.0.1",
"load-grunt-tasks": "^5.1.0", "load-grunt-tasks": "^5.1.0",
"performance-now": "^2.1.0", "performance-now": "^2.1.0",
"quiet-grunt": "^0.2.0", "quiet-grunt": "^0.2.0",
"semver-sort": "^1.0.0",
"sinon": "*", "sinon": "*",
"source-map-support": "^0.5.21", "source-map-support": "^0.5.21"
"semver-sort": "^1.0.0"
}, },
"dependencies": { "dependencies": {
"commander": "^9.0.0", "commander": "^9.0.0",
"jsdom": "^19.0.0" "jsdom": "^19.0.0"
},
"overrides": {
"minimist": "^1.2.6"
} }
} }

6
test/bootstrap.js Normal file
View File

@ -0,0 +1,6 @@
//.webstorm.bootstrap.js
var chai = require('chai');
global.chai = chai;
global.expect = chai.expect;
global.showdown = require('../.build/showdown.js');
global.getDefaultOpts = require('./optionswp.js').getDefaultOpts;

View File

@ -8,7 +8,7 @@
require('source-map-support').install(); require('source-map-support').install();
require('chai').should(); require('chai').should();
var fs = require('fs'); let fs = require('fs');
function getTestSuite (dir) { function getTestSuite (dir) {
return fs.readdirSync(dir) return fs.readdirSync(dir)
@ -17,20 +17,20 @@
} }
function getJsonTestSuite (file) { function getJsonTestSuite (file) {
var json = JSON.parse(fs.readFileSync(file, 'utf8')); let json = JSON.parse(fs.readFileSync(file, 'utf8'));
return mapJson(json, file); return mapJson(json, file);
} }
function filter () { function filter () {
return function (file) { return function (file) {
var ext = file.slice(-3); let ext = file.slice(-3);
return (ext === '.md'); return (ext === '.md');
}; };
} }
function map (dir) { function map (dir) {
return function (file) { return function (file) {
var oFile = 'file://' + process.cwd().replace(/\\/g, '/') + dir + file, let oFile = 'file://' + process.cwd().replace(/\\/g, '/') + dir + file,
name = file.replace('.md', ''), name = file.replace('.md', ''),
htmlPath = dir + name + '.html', htmlPath = dir + name + '.html',
html = fs.readFileSync(htmlPath, 'utf8'), html = fs.readFileSync(htmlPath, 'utf8'),
@ -47,12 +47,12 @@
} }
function mapJson (jsonArray, file) { function mapJson (jsonArray, file) {
var tcObj = {}; let tcObj = {};
for (var i = 0; i < jsonArray.length; ++i) { for (let i = 0; i < jsonArray.length; ++i) {
var section = jsonArray[i].section; let section = jsonArray[i].section;
var name = jsonArray[i].section + '_' + jsonArray[i].example; let name = jsonArray[i].section + '_' + jsonArray[i].example;
var md = jsonArray[i].markdown; let md = jsonArray[i].markdown;
var html = jsonArray[i].html; let html = jsonArray[i].html;
if (!tcObj.hasOwnProperty(section)) { if (!tcObj.hasOwnProperty(section)) {
tcObj[section] = []; tcObj[section] = [];
} }

View File

@ -1,16 +1,15 @@
/** /**
* Created by Estevao on 31-05-2015. * Created by Estevao on 31-05-2015.
*/ */
require('source-map-support').install(); //let showdown = require('../../.build/showdown.js') || require('showdown');
require('chai').should(); chai.should();
require('sinon');
var showdown = require('../../.build/showdown.js');
describe('showdown.Converter', function () { describe('showdown.Converter', function () {
'use strict'; 'use strict';
describe('option methods', function () { describe('option methods', function () {
var converter = new showdown.Converter(); let converter = new showdown.Converter();
it('setOption() should set option foo=baz', function () { it('setOption() should set option foo=baz', function () {
converter.setOption('foo', 'baz'); converter.setOption('foo', 'baz');
@ -21,14 +20,14 @@ describe('showdown.Converter', function () {
}); });
it('getOptions() should contain foo=baz', function () { it('getOptions() should contain foo=baz', function () {
var options = converter.getOptions(); let options = converter.getOptions();
options.should.have.ownProperty('foo'); options.should.have.ownProperty('foo');
options.foo.should.equal('baz'); options.foo.should.equal('baz');
}); });
}); });
describe('metadata methods', function () { describe('metadata methods', function () {
var converter = new showdown.Converter(); let converter = new showdown.Converter();
it('_setMetadataPair() should set foo to bar', function () { it('_setMetadataPair() should set foo to bar', function () {
converter._setMetadataPair('foo', 'bar'); converter._setMetadataPair('foo', 'bar');
@ -47,18 +46,18 @@ describe('showdown.Converter', function () {
* Test setFlavor('github') * Test setFlavor('github')
*/ */
describe('github', function () { describe('github', function () {
var converter = new showdown.Converter(), let converter = new showdown.Converter(),
ghOpts = showdown.getFlavorOptions('github'); ghOpts = showdown.getFlavorOptions('github');
converter.setFlavor('github'); converter.setFlavor('github');
for (var opt in ghOpts) { for (let opt in ghOpts) {
if (ghOpts.hasOwnProperty(opt)) { if (ghOpts.hasOwnProperty(opt)) {
check(opt, ghOpts[opt]); check(opt, ghOpts[opt]);
} }
} }
function check (key, val) { function check (key, val) {
it('should set ' + opt + ' to ' + val, function () { it('should set ' + key + ' to ' + val, function () {
converter.getOption(key).should.equal(val); converter.getOption(key).should.equal(val);
}); });
} }
@ -72,19 +71,19 @@ describe('showdown.Converter', function () {
describe('flavor', function () { describe('flavor', function () {
it('should be vanilla by default', function () { it('should be vanilla by default', function () {
var converter = new showdown.Converter(); let converter = new showdown.Converter();
converter.getFlavor().should.equal('vanilla'); converter.getFlavor().should.equal('vanilla');
}); });
it('should be changed if global option is changed', function () { it('should be changed if global option is changed', function () {
showdown.setFlavor('github'); showdown.setFlavor('github');
var converter = new showdown.Converter(); let converter = new showdown.Converter();
converter.getFlavor().should.equal('github'); converter.getFlavor().should.equal('github');
showdown.setFlavor('vanilla'); showdown.setFlavor('vanilla');
}); });
it('should not be changed if converter is initialized before global change', function () { it('should not be changed if converter is initialized before global change', function () {
var converter = new showdown.Converter(); let converter = new showdown.Converter();
showdown.setFlavor('github'); showdown.setFlavor('github');
converter.getFlavor().should.equal('vanilla'); converter.getFlavor().should.equal('vanilla');
showdown.setFlavor('vanilla'); showdown.setFlavor('vanilla');
@ -93,7 +92,7 @@ describe('showdown.Converter', function () {
}); });
describe('extension methods', function () { describe('extension methods', function () {
var extObjMock = { let extObjMock = {
type: 'lang', type: 'lang',
filter: function () {} filter: function () {}
}, },
@ -102,13 +101,13 @@ describe('showdown.Converter', function () {
}; };
it('addExtension() should add an extension Object', function () { it('addExtension() should add an extension Object', function () {
var converter = new showdown.Converter(); let converter = new showdown.Converter();
converter.addExtension(extObjMock); converter.addExtension(extObjMock);
converter.getAllExtensions().language.should.contain(extObjMock); converter.getAllExtensions().language.should.contain(extObjMock);
}); });
it('addExtension() should unwrap an extension wrapped in a function', function () { it('addExtension() should unwrap an extension wrapped in a function', function () {
var converter = new showdown.Converter(); let converter = new showdown.Converter();
converter.addExtension(extObjFunc); converter.addExtension(extObjFunc);
converter.getAllExtensions().language.should.contain(extObjMock); converter.getAllExtensions().language.should.contain(extObjMock);
@ -116,7 +115,7 @@ describe('showdown.Converter', function () {
it('useExtension() should use a previous registered extension in showdown', function () { it('useExtension() should use a previous registered extension in showdown', function () {
showdown.extension('foo', extObjMock); showdown.extension('foo', extObjMock);
var converter = new showdown.Converter(); let converter = new showdown.Converter();
converter.useExtension('foo'); converter.useExtension('foo');
converter.getAllExtensions().language.should.contain(extObjMock); converter.getAllExtensions().language.should.contain(extObjMock);
@ -124,7 +123,7 @@ describe('showdown.Converter', function () {
}); });
it('removeExtension() should remove an added extension', function () { it('removeExtension() should remove an added extension', function () {
var converter = new showdown.Converter(); let converter = new showdown.Converter();
converter.addExtension(extObjMock); converter.addExtension(extObjMock);
converter.removeExtension(extObjMock); converter.removeExtension(extObjMock);
@ -133,7 +132,7 @@ describe('showdown.Converter', function () {
}); });
describe('events', function () { describe('events', function () {
var events = [ let events = [
'makehtml.anchors', 'makehtml.anchors',
'makehtml.autoLinks', 'makehtml.autoLinks',
'makehtml.blockGamut', 'makehtml.blockGamut',
@ -151,17 +150,17 @@ describe('showdown.Converter', function () {
//'tables' //'tables'
]; ];
for (var i = 0; i < events.length; ++i) { for (let i = 0; i < events.length; ++i) {
runListener(events[i] + '.before'); runListener(events[i] + '.before');
runListener(events[i] + '.after'); runListener(events[i] + '.after');
} }
function runListener (name) { function runListener (name) {
it('should listen to ' + name, function () { it('should listen to ' + name, function () {
var converter = new showdown.Converter(); let converter = new showdown.Converter();
converter.listen(name, function (event) { converter.listen(name, function (event) {
var evtName = event.getName(); let evtName = event.getName();
var text = event.getCapturedText(); let text = event.getCapturedText();
evtName.should.equal(name.toLowerCase()); evtName.should.equal(name.toLowerCase());
text.should.match(/^[\s\S]*foo[\s\S]*$/); text.should.match(/^[\s\S]*foo[\s\S]*$/);
return text; return text;

View File

@ -1,16 +1,15 @@
/** /**
* Created by Estevao on 15-01-2015. * Created by Tivie on 15-01-2015.
*/ */
require('source-map-support').install(); //let showdown = require('../../.build/showdown.js') || require('showdown');
require('chai').should(); chai.should();
require('sinon');
var showdown = require('../../.build/showdown.js');
describe('showdown.Converter', function () { describe('showdown.Converter', function () {
'use strict'; 'use strict';
describe('Converter.options extensions', function () { describe('Converter.options extensions', function () {
var runCount; let runCount;
showdown.extension('testext', function () { showdown.extension('testext', function () {
return [{ return [{
type: 'output', type: 'output',
@ -21,7 +20,7 @@ describe('showdown.Converter', function () {
}]; }];
}); });
var converter = new showdown.Converter({extensions: ['testext']}); let converter = new showdown.Converter({extensions: ['testext']});
it('output extensions should run once', function () { it('output extensions should run once', function () {
runCount = 0; runCount = 0;
@ -31,36 +30,36 @@ describe('showdown.Converter', function () {
}); });
describe('makeHtml() with option omitExtraWLInCodeBlocks', function () { describe('makeHtml() with option omitExtraWLInCodeBlocks', function () {
var converter = new showdown.Converter({omitExtraWLInCodeBlocks: true}), let converter = new showdown.Converter({omitExtraWLInCodeBlocks: true}),
text = 'var foo = bar;', text = 'var foo = bar;',
html = converter.makeHtml(' ' + text); html = converter.makeHtml(' ' + text);
it('should omit extra line after code tag', function () { it('should omit extra line after code tag', function () {
var expectedHtml = '<pre><code>' + text + '</code></pre>'; let expectedHtml = '<pre><code>' + text + '</code></pre>';
html.should.equal(expectedHtml); html.should.equal(expectedHtml);
}); });
}); });
describe('makeHtml() with option prefixHeaderId', function () { describe('makeHtml() with option prefixHeaderId', function () {
var converter = new showdown.Converter(), let converter = new showdown.Converter(),
text = 'foo header'; text = 'foo header';
it('should prefix header id with "section"', function () { it('should prefix header id with "section"', function () {
converter.setOption('prefixHeaderId', true); converter.setOption('prefixHeaderId', true);
var html = converter.makeHtml('# ' + text), let html = converter.makeHtml('# ' + text),
expectedHtml = '<h1 id="sectionfooheader">' + text + '</h1>'; expectedHtml = '<h1 id="sectionfooheader">' + text + '</h1>';
html.should.equal(expectedHtml); html.should.equal(expectedHtml);
}); });
it('should prefix header id with custom string', function () { it('should prefix header id with custom string', function () {
converter.setOption('prefixHeaderId', 'blabla'); converter.setOption('prefixHeaderId', 'blabla');
var html = converter.makeHtml('# ' + text), let html = converter.makeHtml('# ' + text),
expectedHtml = '<h1 id="blablafooheader">' + text + '</h1>'; expectedHtml = '<h1 id="blablafooheader">' + text + '</h1>';
html.should.equal(expectedHtml); html.should.equal(expectedHtml);
}); });
}); });
describe('makeHtml() with option metadata', function () { describe('makeHtml() with option metadata', function () {
var converter = new showdown.Converter(), let converter = new showdown.Converter(),
text1 = text1 =
'---SIMPLE\n' + '---SIMPLE\n' +
'foo: bar\n' + 'foo: bar\n' +
@ -75,7 +74,7 @@ describe('showdown.Converter', function () {
it('should correctly set metadata', function () { it('should correctly set metadata', function () {
converter.setOption('metadata', true); converter.setOption('metadata', true);
var expectedHtml = '', let expectedHtml = '',
expectedObj = {foo: 'bar', baz: 'bazinga'}, expectedObj = {foo: 'bar', baz: 'bazinga'},
expectedRaw = 'foo: bar\nbaz: bazinga', expectedRaw = 'foo: bar\nbaz: bazinga',
expectedFormat = 'SIMPLE'; expectedFormat = 'SIMPLE';
@ -87,7 +86,7 @@ describe('showdown.Converter', function () {
it('consecutive calls should reset metadata', function () { it('consecutive calls should reset metadata', function () {
converter.makeHtml(text2); converter.makeHtml(text2);
var expectedObj = {a: 'b', c: '123'}, let expectedObj = {a: 'b', c: '123'},
expectedRaw = 'a: b\nc: 123', expectedRaw = 'a: b\nc: 123',
expectedFormat = 'TIVIE'; expectedFormat = 'TIVIE';
converter.getMetadata().should.eql(expectedObj); converter.getMetadata().should.eql(expectedObj);

View File

@ -1,21 +1,19 @@
/** /**
* Created by Estevao on 15-01-2015. * Created by Estevao on 15-01-2015.
*/ */
require('source-map-support').install(); //let showdown = require('../../.build/showdown.js') || require('showdown');
require('chai').should(); chai.should();
require('sinon');
var showdown = require('../../.build/showdown.js');
describe('showdown.Converter', function () { describe('showdown.Converter', function () {
'use strict'; 'use strict';
describe('makeMarkdown()', function () { describe('makeMarkdown()', function () {
var converter = new showdown.Converter(); let converter = new showdown.Converter();
it('should parse a simple html string', function () { it('should parse a simple html string', function () {
var html = '<a href="/somefoo.html">a link</a>\n'; let html = '<a href="/somefoo.html">a link</a>\n';
var md = '[a link](</somefoo.html>)'; let md = '[a link](</somefoo.html>)';
converter.makeMarkdown(html).should.equal(md); converter.makeMarkdown(html).should.equal(md);
}); });

View File

@ -1,10 +1,7 @@
/** /**
* Created by Tivie on 27/01/2017. * Created by Tivie on 27/01/2017.
*/ */
require('source-map-support').install(); chai.should();
require('chai').should();
require('sinon');
var showdown = require('../../.build/showdown.js');
/*jshint expr: true*/ /*jshint expr: true*/
/*jshint -W053 */ /*jshint -W053 */
/*jshint -W010 */ /*jshint -W010 */
@ -12,7 +9,7 @@ var showdown = require('../../.build/showdown.js');
describe('encodeEmailAddress()', function () { describe('encodeEmailAddress()', function () {
'use strict'; 'use strict';
var encoder = showdown.helper.encodeEmailAddress, let encoder = showdown.helper.encodeEmailAddress,
email = 'foobar@example.com', email = 'foobar@example.com',
encodedEmail = encoder(email), encodedEmail = encoder(email),
encodedEmail2 = encoder(email); encodedEmail2 = encoder(email);
@ -26,7 +23,7 @@ describe('encodeEmailAddress()', function () {
}); });
it('should decode to original email', function () { it('should decode to original email', function () {
var decodedEmail = encodedEmail.replace(/&#(.+?);/g, function (wm, cc) { let decodedEmail = encodedEmail.replace(/&#(.+?);/g, function (wm, cc) {
if (cc.charAt(0) === 'x') { if (cc.charAt(0) === 'x') {
//hex //hex
return String.fromCharCode('0' + cc); return String.fromCharCode('0' + cc);
@ -41,7 +38,7 @@ describe('encodeEmailAddress()', function () {
describe('isString()', function () { describe('isString()', function () {
'use strict'; 'use strict';
var isString = showdown.helper.isString; let isString = showdown.helper.isString;
it('should return true for new String Object', function () { it('should return true for new String Object', function () {
isString(new String('some string')).should.be.true; isString(new String('some string')).should.be.true;
@ -70,7 +67,7 @@ describe('isString()', function () {
describe('isFunction()', function () { describe('isFunction()', function () {
'use strict'; 'use strict';
var isFunction = showdown.helper.isFunction; let isFunction = showdown.helper.isFunction;
it('should return true for closures', function () { it('should return true for closures', function () {
isFunction(function () {}).should.be.true; isFunction(function () {}).should.be.true;
@ -81,8 +78,8 @@ describe('isFunction()', function () {
isFunction(foo).should.be.true; isFunction(foo).should.be.true;
}); });
it('should return true for function variables', function () { it('should return true for function letiables', function () {
var bar = function () {}; let bar = function () {};
isFunction(bar).should.be.true; isFunction(bar).should.be.true;
}); });
@ -101,14 +98,14 @@ describe('isFunction()', function () {
describe('isArray()', function () { describe('isArray()', function () {
'use strict'; 'use strict';
var isArray = showdown.helper.isArray; let isArray = showdown.helper.isArray;
it('should return true for short syntax arrays', function () { it('should return true for short syntax arrays', function () {
isArray([]).should.be.true; isArray([]).should.be.true;
}); });
it('should return true for array objects', function () { it('should return true for array objects', function () {
var myArr = new Array(); let myArr = new Array();
isArray(myArr).should.be.true; isArray(myArr).should.be.true;
}); });
@ -131,14 +128,14 @@ describe('isArray()', function () {
describe('isUndefined()', function () { describe('isUndefined()', function () {
'use strict'; 'use strict';
var isUndefined = showdown.helper.isUndefined; let isUndefined = showdown.helper.isUndefined;
it('should return true if nothing is passed', function () { it('should return true if nothing is passed', function () {
isUndefined().should.be.true; isUndefined().should.be.true;
}); });
it('should return true if a variable is initialized but not defined', function () { it('should return true if a letiable is initialized but not defined', function () {
var myVar; let myVar;
isUndefined(myVar).should.be.true; isUndefined(myVar).should.be.true;
}); });
@ -168,15 +165,15 @@ describe('isUndefined()', function () {
describe('stdExtName()', function () { describe('stdExtName()', function () {
'use strict'; 'use strict';
var stdExtName = showdown.helper.stdExtName; let stdExtName = showdown.helper.stdExtName;
it('should remove certain chars', function () { it('should remove certain chars', function () {
var str = 'bla_- \nbla'; let str = 'bla_- \nbla';
//[_?*+\/\\.^-] //[_?*+\/\\.^-]
stdExtName(str).should.not.match(/[_?*+\/\\.^-]/g); stdExtName(str).should.not.match(/[_?*+\/\\.^-]/g);
}); });
it('should make everything lowercase', function () { it('should make everything lowercase', function () {
var str = 'BLABLA'; let str = 'BLABLA';
//[_?*+\/\\.^-] //[_?*+\/\\.^-]
stdExtName(str).should.equal('blabla'); stdExtName(str).should.equal('blabla');
}); });
@ -184,7 +181,7 @@ describe('stdExtName()', function () {
describe('forEach()', function () { describe('forEach()', function () {
'use strict'; 'use strict';
var forEach = showdown.helper.forEach; let forEach = showdown.helper.forEach;
it('should throw an error if first parameter is undefined', function () { it('should throw an error if first parameter is undefined', function () {
(function () {forEach();}).should.throw('obj param is required'); (function () {forEach();}).should.throw('obj param is required');
@ -207,7 +204,7 @@ describe('forEach()', function () {
}); });
it('should iterate array items', function () { it('should iterate array items', function () {
var myArray = ['banana', 'orange', 'grape']; let myArray = ['banana', 'orange', 'grape'];
forEach(myArray, function (val, key, obj) { forEach(myArray, function (val, key, obj) {
key.should.be.a('number'); key.should.be.a('number');
(key % 1).should.equal(0); (key % 1).should.equal(0);
@ -217,7 +214,7 @@ describe('forEach()', function () {
}); });
it('should iterate over object properties', function () { it('should iterate over object properties', function () {
var myObj = {foo: 'banana', bar: 'orange', baz: 'grape'}; let myObj = {foo: 'banana', bar: 'orange', baz: 'grape'};
forEach(myObj, function (val, key, obj) { forEach(myObj, function (val, key, obj) {
myObj.should.have.ownProperty(key); myObj.should.have.ownProperty(key);
val.should.equal(myObj[key]); val.should.equal(myObj[key]);
@ -226,7 +223,7 @@ describe('forEach()', function () {
}); });
it('should iterate only over object own properties', function () { it('should iterate only over object own properties', function () {
var Obj1 = {foo: 'banana'}, let Obj1 = {foo: 'banana'},
myObj = Object.create(Obj1); myObj = Object.create(Obj1);
myObj.bar = 'orange'; myObj.bar = 'orange';
myObj.baz = 'grape'; myObj.baz = 'grape';
@ -244,10 +241,10 @@ describe('forEach()', function () {
describe('matchRecursiveRegExp()', function () { describe('matchRecursiveRegExp()', function () {
'use strict'; 'use strict';
var rRegExp = showdown.helper.matchRecursiveRegExp; let rRegExp = showdown.helper.matchRecursiveRegExp;
it('should match nested elements', function () { it('should match nested elements', function () {
var result = rRegExp('<div><div>a</div></div>', '<div\\b[^>]*>', '</div>', 'gim'); let result = rRegExp('<div><div>a</div></div>', '<div\\b[^>]*>', '</div>', 'gim');
result.should.deep.equal([['<div><div>a</div></div>', '<div>a</div>', '<div>', '</div>']]); result.should.deep.equal([['<div><div>a</div></div>', '<div>a</div>', '<div>', '</div>']]);
}); });
@ -256,9 +253,11 @@ describe('matchRecursiveRegExp()', function () {
describe('repeat()', function () { describe('repeat()', function () {
'use strict'; 'use strict';
it('work produce the same output as String.prototype.repeat()', function () { it('work produce the same output as String.prototype.repeat()', function () {
var str = 'foo', if (typeof String.prototype.repeat !== 'undefined') {
expected = str.repeat(100), let str = 'foo',
actual = showdown.helper.repeat(str, 100); expected = str.repeat(100),
expected.should.equal(actual); actual = showdown.helper.repeat(str, 100);
expected.should.equal(actual);
}
}); });
}); });

View File

@ -1,9 +1,7 @@
require('source-map-support').install(); /**
require('chai').should(); * Created by Tivie on 27/01/2017.
require('sinon'); */
var expect = require('chai').expect, //let showdown = require('../../.build/showdown.js') || require('showdown');
showdown = require('../../.build/showdown.js');
describe('showdown.options', function () { describe('showdown.options', function () {
'use strict'; 'use strict';
@ -19,7 +17,7 @@ describe('showdown.options', function () {
describe('getDefaultOptions()', function () { describe('getDefaultOptions()', function () {
it('should get default options', function () { it('should get default options', function () {
var opts = require('./optionswp.js').getDefaultOpts(true); let opts = getDefaultOpts(true);
expect(showdown.getDefaultOptions()).to.be.eql(opts); expect(showdown.getDefaultOptions()).to.be.eql(opts);
}); });
}); });
@ -28,7 +26,7 @@ describe('showdown.options', function () {
describe('showdown.extension()', function () { describe('showdown.extension()', function () {
'use strict'; 'use strict';
var extObjMock = { let extObjMock = {
type: 'lang', type: 'lang',
filter: function () {} filter: function () {}
}, },
@ -36,6 +34,8 @@ describe('showdown.extension()', function () {
return extObjMock; return extObjMock;
}; };
/*
// very flimsy test
describe('file loading', function () { describe('file loading', function () {
beforeEach(function () { beforeEach(function () {
@ -52,7 +52,7 @@ describe('showdown.extension()', function () {
}); });
}); });
*/
describe('objects', function () { describe('objects', function () {
it('should register an extension object', function () { it('should register an extension object', function () {
@ -77,14 +77,14 @@ describe('showdown.extension()', function () {
}); });
it('should refuse to register a generic object', function () { it('should refuse to register a generic object', function () {
var fn = function () { let fn = function () {
showdown.extension('foo', {}); showdown.extension('foo', {});
}; };
expect(fn).to.throw(); expect(fn).to.throw();
}); });
it('should refuse to register an extension with invalid type', function () { it('should refuse to register an extension with invalid type', function () {
var fn = function () { let fn = function () {
showdown.extension('foo', { showdown.extension('foo', {
type: 'foo' type: 'foo'
}); });
@ -93,7 +93,7 @@ describe('showdown.extension()', function () {
}); });
it('should refuse to register an extension without regex or filter', function () { it('should refuse to register an extension without regex or filter', function () {
var fn = function () { let fn = function () {
showdown.extension('foo', { showdown.extension('foo', {
type: 'lang' type: 'lang'
}); });
@ -102,7 +102,7 @@ describe('showdown.extension()', function () {
}); });
it('should refuse to register a listener extension without a listeners property', function () { it('should refuse to register a listener extension without a listeners property', function () {
var fn = function () { let fn = function () {
showdown.extension('foo', { showdown.extension('foo', {
type: 'listener' type: 'listener'
}); });
@ -120,7 +120,7 @@ describe('showdown.extension()', function () {
describe('showdown.getAllExtensions()', function () { describe('showdown.getAllExtensions()', function () {
'use strict'; 'use strict';
var extObjMock = { let extObjMock = {
type: 'lang', type: 'lang',
filter: function () {} filter: function () {}
}; };
@ -141,9 +141,9 @@ describe('showdown.setFlavor()', function () {
it('should set options correctly', function () { it('should set options correctly', function () {
showdown.setFlavor('github'); showdown.setFlavor('github');
var ghOpts = showdown.getFlavorOptions('github'), let ghOpts = showdown.getFlavorOptions('github'),
shOpts = showdown.getOptions(); shOpts = showdown.getOptions();
for (var opt in ghOpts) { for (let opt in ghOpts) {
if (ghOpts.hasOwnProperty(opt)) { if (ghOpts.hasOwnProperty(opt)) {
shOpts.should.have.property(opt); shOpts.should.have.property(opt);
shOpts[opt].should.equal(ghOpts[opt]); shOpts[opt].should.equal(ghOpts[opt]);
@ -154,10 +154,10 @@ describe('showdown.setFlavor()', function () {
it('should switch between flavors correctly', function () { it('should switch between flavors correctly', function () {
showdown.setFlavor('github'); showdown.setFlavor('github');
var ghOpts = showdown.getFlavorOptions('github'), let ghOpts = showdown.getFlavorOptions('github'),
shOpts = showdown.getOptions(), shOpts = showdown.getOptions(),
dfOpts = showdown.getDefaultOptions(); dfOpts = showdown.getDefaultOptions();
for (var opt in dfOpts) { for (let opt in dfOpts) {
if (ghOpts.hasOwnProperty(opt)) { if (ghOpts.hasOwnProperty(opt)) {
shOpts[opt].should.equal(ghOpts[opt]); shOpts[opt].should.equal(ghOpts[opt]);
} else { } else {
@ -165,9 +165,9 @@ describe('showdown.setFlavor()', function () {
} }
} }
showdown.setFlavor('original'); showdown.setFlavor('original');
var orOpts = showdown.getFlavorOptions('original'); let orOpts = showdown.getFlavorOptions('original');
shOpts = showdown.getOptions(); shOpts = showdown.getOptions();
for (opt in dfOpts) { for (let opt in dfOpts) {
if (orOpts.hasOwnProperty(opt)) { if (orOpts.hasOwnProperty(opt)) {
shOpts[opt].should.equal(orOpts[opt]); shOpts[opt].should.equal(orOpts[opt]);
} else { } else {