mirror of
https://github.com/showdownjs/showdown.git
synced 2024-03-22 13:30:55 +08:00
fix(cli): cli now works properly
The CLI was completely rewrote. Changed dependency from yargs to commanderjs, which is cleaner, faster and has no dependencies. Also added a complete testsuite for the cli. Closes #893, #894
This commit is contained in:
parent
612dad0682
commit
3871765ac1
53
Gruntfile.js
53
Gruntfile.js
|
@ -13,12 +13,12 @@ module.exports = function (grunt) {
|
|||
pkg: grunt.file.readJSON('package.json'),
|
||||
|
||||
concat: {
|
||||
options: {
|
||||
sourceMap: true,
|
||||
banner: ';/*! <%= pkg.name %> v <%= pkg.version %> - <%= grunt.template.today("dd-mm-yyyy") %> */\n(function(){\n',
|
||||
footer: '}).call(this);\n'
|
||||
},
|
||||
dist: {
|
||||
options: {
|
||||
sourceMap: true,
|
||||
banner: ';/*! <%= pkg.name %> v <%= pkg.version %> - <%= grunt.template.today("dd-mm-yyyy") %> */\n(function(){\n',
|
||||
footer: '}).call(this);\n'
|
||||
},
|
||||
src: [
|
||||
'src/options.js',
|
||||
'src/showdown.js',
|
||||
|
@ -30,6 +30,12 @@ module.exports = function (grunt) {
|
|||
],
|
||||
dest: 'dist/<%= pkg.name %>.js'
|
||||
},
|
||||
cli: {
|
||||
src: [
|
||||
'src/cli/cli.js'
|
||||
],
|
||||
dest: 'bin/showdown.js'
|
||||
},
|
||||
test: {
|
||||
src: '<%= concat.dist.src %>',
|
||||
dest: '.build/<%= pkg.name %>.js',
|
||||
|
@ -42,14 +48,23 @@ module.exports = function (grunt) {
|
|||
clean: ['.build/'],
|
||||
|
||||
uglify: {
|
||||
options: {
|
||||
sourceMap: true,
|
||||
banner: '/*! <%= pkg.name %> v <%= pkg.version %> - <%= grunt.template.today("dd-mm-yyyy") %> */'
|
||||
},
|
||||
dist: {
|
||||
options: {
|
||||
sourceMap: true,
|
||||
banner: '/*! <%= pkg.name %> v <%= pkg.version %> - <%= grunt.template.today("dd-mm-yyyy") %> */'
|
||||
},
|
||||
files: {
|
||||
'dist/<%= pkg.name %>.min.js': ['<%= concat.dist.dest %>']
|
||||
}
|
||||
},
|
||||
cli: {
|
||||
options: {
|
||||
sourceMap: false,
|
||||
banner: '#!/usr/bin/env node'
|
||||
},
|
||||
files: {
|
||||
'bin/showdown.js': ['<%= concat.cli.dest %>']
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -164,6 +179,15 @@ module.exports = function (grunt) {
|
|||
ignoreLeaks: false,
|
||||
reporter: 'spec'
|
||||
}
|
||||
},
|
||||
cli: {
|
||||
src: 'test/node/testsuite.cli.js',
|
||||
options: {
|
||||
globals: ['should'],
|
||||
timeout: 3000,
|
||||
ignoreLeaks: false,
|
||||
reporter: 'spec'
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -227,19 +251,14 @@ module.exports = function (grunt) {
|
|||
grunt.task.run(['lint', 'concat:test', 'simplemocha:single', 'clean']);
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Test in Legacy Node
|
||||
*/
|
||||
grunt.registerTask('test-old', ['concat:test', 'simplemocha:node', 'clean']);
|
||||
|
||||
/**
|
||||
* Tasks for new node versions
|
||||
*/
|
||||
grunt.registerTask('test', ['clean', 'lint', 'concat:test', 'simplemocha:node', 'clean']);
|
||||
grunt.registerTask('test-cli', ['clean', 'lint', 'concat:test', 'simplemocha:cli', 'clean']);
|
||||
grunt.registerTask('performance', ['concat:test', 'performancejs', 'clean']);
|
||||
grunt.registerTask('build', ['test', 'concat:dist', 'uglify', 'endline']);
|
||||
grunt.registerTask('prep-release', ['build', 'generate-changelog']);
|
||||
grunt.registerTask('build', ['test', 'concat:dist', 'concat:cli', 'uglify:dist', 'uglify:cli', 'endline']);
|
||||
grunt.registerTask('prep-release', ['build', 'performance', 'generate-changelog']);
|
||||
|
||||
// Default task(s).
|
||||
grunt.registerTask('default', ['test']);
|
||||
|
|
BIN
bin/showdown.js
BIN
bin/showdown.js
Binary file not shown.
BIN
dist/showdown.js
vendored
BIN
dist/showdown.js
vendored
Binary file not shown.
BIN
dist/showdown.js.map
vendored
BIN
dist/showdown.js.map
vendored
Binary file not shown.
BIN
dist/showdown.min.js
vendored
BIN
dist/showdown.min.js
vendored
Binary file not shown.
BIN
dist/showdown.min.js.map
vendored
BIN
dist/showdown.min.js.map
vendored
Binary file not shown.
276
package-lock.json
generated
276
package-lock.json
generated
|
@ -1,21 +1,22 @@
|
|||
{
|
||||
"name": "showdown",
|
||||
"version": "2.0.0",
|
||||
"version": "2.0.1",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "showdown",
|
||||
"version": "2.0.0",
|
||||
"version": "2.0.1",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"yargs": "^17.2.1"
|
||||
"commander": "^9.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"showdown": "bin/showdown.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"chai": "^4.3.4",
|
||||
"chai": "*",
|
||||
"chai-match": "*",
|
||||
"grunt": "^1.4.1",
|
||||
"grunt-contrib-clean": "^2.0.0",
|
||||
"grunt-contrib-concat": "^2.0.0",
|
||||
|
@ -32,14 +33,14 @@
|
|||
"quiet-grunt": "^0.2.0",
|
||||
"semver": "^7.3.0",
|
||||
"semver-sort": "^0.0.4",
|
||||
"sinon": "^12.0.1",
|
||||
"sinon": "*",
|
||||
"source-map-support": "^0.5.20"
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint/eslintrc": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.1.0.tgz",
|
||||
"integrity": "sha512-C1DfL7XX4nPqGd6jcP01W9pVM1HYCuUkFk1432D7F0v3JSlUIeOYn9oCoi3eoLZ+iwBSb29BMFxxny0YrrEZqg==",
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.0.tgz",
|
||||
"integrity": "sha512-igm9SjJHNEJRiUnecP/1R5T3wKLEJ7pL6e2P+GUSfCd0dGjPYYZve08uzw8L2J8foVHFz+NGu12JxRcU2gGo6w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ajv": "^6.12.4",
|
||||
|
@ -84,9 +85,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@humanwhocodes/config-array": {
|
||||
"version": "0.9.3",
|
||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.3.tgz",
|
||||
"integrity": "sha512-3xSMlXHh03hCcCmFc0rbKp3Ivt2PFEJnQUJDDMTJQ2wkECZWdq4GePs2ctc5H8zV+cHPaq8k2vU8mrQjA6iHdQ==",
|
||||
"version": "0.9.5",
|
||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz",
|
||||
"integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@humanwhocodes/object-schema": "^1.2.1",
|
||||
|
@ -113,9 +114,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@sinonjs/fake-timers": {
|
||||
"version": "8.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz",
|
||||
"integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==",
|
||||
"version": "9.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.0.tgz",
|
||||
"integrity": "sha512-M8vapsv9qQupMdzrVzkn5rb9jG7aUTEPAZdMtME2PuBaefksFZVE2C1g4LBRTkF/k3nRDNbDc5tp5NFC1PEYxA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@sinonjs/commons": "^1.7.0"
|
||||
|
@ -264,6 +265,7 @@
|
|||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
|
@ -272,6 +274,7 @@
|
|||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"color-convert": "^2.0.1"
|
||||
},
|
||||
|
@ -493,6 +496,12 @@
|
|||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/chai-match": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/chai-match/-/chai-match-1.1.1.tgz",
|
||||
"integrity": "sha1-OfsKLmt8j2OG3P6tSNFIqRX6bEY=",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/chalk": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
|
||||
|
@ -574,6 +583,7 @@
|
|||
"version": "7.0.4",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
|
||||
"integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"string-width": "^4.2.0",
|
||||
"strip-ansi": "^6.0.0",
|
||||
|
@ -584,6 +594,7 @@
|
|||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"color-name": "~1.1.4"
|
||||
},
|
||||
|
@ -594,7 +605,8 @@
|
|||
"node_modules/color-name": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/colors": {
|
||||
"version": "1.1.2",
|
||||
|
@ -617,6 +629,14 @@
|
|||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/commander": {
|
||||
"version": "9.0.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-9.0.0.tgz",
|
||||
"integrity": "sha512-JJfP2saEKbQqvW+FI93OYUB4ByV5cizMpFMiiJI8xDbBvQvSkIk0VvQdn1CZ8mqAO8Loq2h0gYTYtDFUZUeERw==",
|
||||
"engines": {
|
||||
"node": "^12.20.0 || >=14"
|
||||
}
|
||||
},
|
||||
"node_modules/compare-func": {
|
||||
"version": "1.3.4",
|
||||
"resolved": "https://registry.npmjs.org/compare-func/-/compare-func-1.3.4.tgz",
|
||||
|
@ -1293,7 +1313,8 @@
|
|||
"node_modules/emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/entities": {
|
||||
"version": "1.0.0",
|
||||
|
@ -1314,6 +1335,7 @@
|
|||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
|
||||
"integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
|
@ -1414,12 +1436,12 @@
|
|||
}
|
||||
},
|
||||
"node_modules/eslint": {
|
||||
"version": "8.9.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.9.0.tgz",
|
||||
"integrity": "sha512-PB09IGwv4F4b0/atrbcMFboF/giawbBLVC7fyDamk5Wtey4Jh2K+rYaBhCAbUyEI4QzB1ly09Uglc9iCtFaG2Q==",
|
||||
"version": "8.10.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.10.0.tgz",
|
||||
"integrity": "sha512-tcI1D9lfVec+R4LE1mNDnzoJ/f71Kl/9Cv4nG47jOueCMBrCCKYXr4AUVS7go6mWYGFD4+EoN6+eXSrEbRzXVw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@eslint/eslintrc": "^1.1.0",
|
||||
"@eslint/eslintrc": "^1.2.0",
|
||||
"@humanwhocodes/config-array": "^0.9.2",
|
||||
"ajv": "^6.10.0",
|
||||
"chalk": "^4.0.0",
|
||||
|
@ -1866,6 +1888,7 @@
|
|||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
|
||||
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": "6.* || 8.* || >= 10.*"
|
||||
}
|
||||
|
@ -2294,14 +2317,14 @@
|
|||
}
|
||||
},
|
||||
"node_modules/grunt-contrib-jshint": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/grunt-contrib-jshint/-/grunt-contrib-jshint-3.1.1.tgz",
|
||||
"integrity": "sha512-EwMY6L91FqTcMlZTVoDeeq/EZL+7MoFyo1rxIea9sxyv73geVggeE37jcUhNbu5hLbxHE82CGIUqitHuR2/q+g==",
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/grunt-contrib-jshint/-/grunt-contrib-jshint-3.2.0.tgz",
|
||||
"integrity": "sha512-pcXWCSZWfoMSvcV4BwH21TUtLtcX0Ms8IGuOPIcLeXK3fud9KclY7iqMKY94jFx8TxZzh028YYtpR+io8DiEaQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"chalk": "^4.1.0",
|
||||
"chalk": "~4.1.2",
|
||||
"hooker": "^0.2.3",
|
||||
"jshint": "~2.13.0"
|
||||
"jshint": "~2.13.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
|
@ -3011,6 +3034,7 @@
|
|||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
|
@ -3875,9 +3899,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/mocha": {
|
||||
"version": "9.2.0",
|
||||
"resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.0.tgz",
|
||||
"integrity": "sha512-kNn7E8g2SzVcq0a77dkphPsDSN7P+iYkqE0ZsGCYWRsoiKjOt+NvXfaagik8vuDa6W5Zw3qxe8Jfpt5qKf+6/Q==",
|
||||
"version": "9.2.1",
|
||||
"resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.1.tgz",
|
||||
"integrity": "sha512-T7uscqjJVS46Pq1XDXyo9Uvey9gd3huT/DD9cYBb4K2Xc/vbKRPUWK067bxDQRK0yIz6Jxk73IrnimvASzBNAQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@ungap/promise-all-settled": "1.1.2",
|
||||
|
@ -3988,24 +4012,6 @@
|
|||
"url": "https://github.com/chalk/supports-color?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/mocha/node_modules/yargs": {
|
||||
"version": "16.2.0",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
|
||||
"integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"cliui": "^7.0.2",
|
||||
"escalade": "^3.1.1",
|
||||
"get-caller-file": "^2.0.5",
|
||||
"require-directory": "^2.1.1",
|
||||
"string-width": "^4.2.0",
|
||||
"y18n": "^5.0.5",
|
||||
"yargs-parser": "^20.2.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/modify-values": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz",
|
||||
|
@ -4774,6 +4780,7 @@
|
|||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
|
||||
"integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
|
@ -4960,16 +4967,16 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/sinon": {
|
||||
"version": "12.0.1",
|
||||
"resolved": "https://registry.npmjs.org/sinon/-/sinon-12.0.1.tgz",
|
||||
"integrity": "sha512-iGu29Xhym33ydkAT+aNQFBINakjq69kKO6ByPvTsm3yyIACfyQttRTP03aBP/I8GfhFmLzrnKwNNkr0ORb1udg==",
|
||||
"version": "13.0.1",
|
||||
"resolved": "https://registry.npmjs.org/sinon/-/sinon-13.0.1.tgz",
|
||||
"integrity": "sha512-8yx2wIvkBjIq/MGY1D9h1LMraYW+z1X0mb648KZnKSdvLasvDu7maa0dFaNYdTDczFgbjNw2tOmWdTk9saVfwQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@sinonjs/commons": "^1.8.3",
|
||||
"@sinonjs/fake-timers": "^8.1.0",
|
||||
"@sinonjs/samsam": "^6.0.2",
|
||||
"@sinonjs/fake-timers": "^9.0.0",
|
||||
"@sinonjs/samsam": "^6.1.1",
|
||||
"diff": "^5.0.0",
|
||||
"nise": "^5.1.0",
|
||||
"nise": "^5.1.1",
|
||||
"supports-color": "^7.2.0"
|
||||
},
|
||||
"funding": {
|
||||
|
@ -5077,6 +5084,7 @@
|
|||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
|
@ -5090,6 +5098,7 @@
|
|||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ansi-regex": "^5.0.1"
|
||||
},
|
||||
|
@ -5287,9 +5296,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/uglify-js": {
|
||||
"version": "3.15.1",
|
||||
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.15.1.tgz",
|
||||
"integrity": "sha512-FAGKF12fWdkpvNJZENacOH0e/83eG6JyVQyanIJaBXCN1J11TUQv1T1/z8S+Z0CG0ZPk1nPcreF/c7lrTd0TEQ==",
|
||||
"version": "3.15.2",
|
||||
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.15.2.tgz",
|
||||
"integrity": "sha512-peeoTk3hSwYdoc9nrdiEJk+gx1ALCtTjdYuKSXMTDqq7n1W7dHPqWDdSi+BPL0ni2YMeHD7hKUSdbj3TZauY2A==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"uglifyjs": "bin/uglifyjs"
|
||||
|
@ -5503,6 +5512,7 @@
|
|||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
|
||||
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ansi-styles": "^4.0.0",
|
||||
"string-width": "^4.1.0",
|
||||
|
@ -5570,6 +5580,7 @@
|
|||
"version": "5.0.8",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
|
||||
"integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
|
@ -5581,20 +5592,21 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/yargs": {
|
||||
"version": "17.3.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.3.1.tgz",
|
||||
"integrity": "sha512-WUANQeVgjLbNsEmGk20f+nlHgOqzRFpiGWVaBrYGYIGANIIu3lWjoyi0fNlFmJkvfhCZ6BXINe7/W2O2bV4iaA==",
|
||||
"version": "16.2.0",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
|
||||
"integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"cliui": "^7.0.2",
|
||||
"escalade": "^3.1.1",
|
||||
"get-caller-file": "^2.0.5",
|
||||
"require-directory": "^2.1.1",
|
||||
"string-width": "^4.2.3",
|
||||
"string-width": "^4.2.0",
|
||||
"y18n": "^5.0.5",
|
||||
"yargs-parser": "^21.0.0"
|
||||
"yargs-parser": "^20.2.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/yargs-parser": {
|
||||
|
@ -5654,14 +5666,6 @@
|
|||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/yargs/node_modules/yargs-parser": {
|
||||
"version": "21.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.0.tgz",
|
||||
"integrity": "sha512-z9kApYUOCwoeZ78rfRYYWdiU/iNL6mwwYlkkZfJoyMR1xps+NEBX5X7XmRpxkZHhXJ6+Ey00IwKxBBSW9FIjyA==",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/yocto-queue": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
|
||||
|
@ -5677,9 +5681,9 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@eslint/eslintrc": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.1.0.tgz",
|
||||
"integrity": "sha512-C1DfL7XX4nPqGd6jcP01W9pVM1HYCuUkFk1432D7F0v3JSlUIeOYn9oCoi3eoLZ+iwBSb29BMFxxny0YrrEZqg==",
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.0.tgz",
|
||||
"integrity": "sha512-igm9SjJHNEJRiUnecP/1R5T3wKLEJ7pL6e2P+GUSfCd0dGjPYYZve08uzw8L2J8foVHFz+NGu12JxRcU2gGo6w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ajv": "^6.12.4",
|
||||
|
@ -5717,9 +5721,9 @@
|
|||
}
|
||||
},
|
||||
"@humanwhocodes/config-array": {
|
||||
"version": "0.9.3",
|
||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.3.tgz",
|
||||
"integrity": "sha512-3xSMlXHh03hCcCmFc0rbKp3Ivt2PFEJnQUJDDMTJQ2wkECZWdq4GePs2ctc5H8zV+cHPaq8k2vU8mrQjA6iHdQ==",
|
||||
"version": "0.9.5",
|
||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz",
|
||||
"integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@humanwhocodes/object-schema": "^1.2.1",
|
||||
|
@ -5743,9 +5747,9 @@
|
|||
}
|
||||
},
|
||||
"@sinonjs/fake-timers": {
|
||||
"version": "8.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz",
|
||||
"integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==",
|
||||
"version": "9.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.0.tgz",
|
||||
"integrity": "sha512-M8vapsv9qQupMdzrVzkn5rb9jG7aUTEPAZdMtME2PuBaefksFZVE2C1g4LBRTkF/k3nRDNbDc5tp5NFC1PEYxA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@sinonjs/commons": "^1.7.0"
|
||||
|
@ -5865,12 +5869,14 @@
|
|||
"ansi-regex": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="
|
||||
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
||||
"dev": true
|
||||
},
|
||||
"ansi-styles": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"color-convert": "^2.0.1"
|
||||
}
|
||||
|
@ -6044,6 +6050,12 @@
|
|||
"type-detect": "^4.0.5"
|
||||
}
|
||||
},
|
||||
"chai-match": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/chai-match/-/chai-match-1.1.1.tgz",
|
||||
"integrity": "sha1-OfsKLmt8j2OG3P6tSNFIqRX6bEY=",
|
||||
"dev": true
|
||||
},
|
||||
"chalk": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
|
||||
|
@ -6101,6 +6113,7 @@
|
|||
"version": "7.0.4",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
|
||||
"integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"string-width": "^4.2.0",
|
||||
"strip-ansi": "^6.0.0",
|
||||
|
@ -6111,6 +6124,7 @@
|
|||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"color-name": "~1.1.4"
|
||||
}
|
||||
|
@ -6118,7 +6132,8 @@
|
|||
"color-name": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||
"dev": true
|
||||
},
|
||||
"colors": {
|
||||
"version": "1.1.2",
|
||||
|
@ -6135,6 +6150,11 @@
|
|||
"delayed-stream": "~1.0.0"
|
||||
}
|
||||
},
|
||||
"commander": {
|
||||
"version": "9.0.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-9.0.0.tgz",
|
||||
"integrity": "sha512-JJfP2saEKbQqvW+FI93OYUB4ByV5cizMpFMiiJI8xDbBvQvSkIk0VvQdn1CZ8mqAO8Loq2h0gYTYtDFUZUeERw=="
|
||||
},
|
||||
"compare-func": {
|
||||
"version": "1.3.4",
|
||||
"resolved": "https://registry.npmjs.org/compare-func/-/compare-func-1.3.4.tgz",
|
||||
|
@ -6701,7 +6721,8 @@
|
|||
"emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
|
||||
"dev": true
|
||||
},
|
||||
"entities": {
|
||||
"version": "1.0.0",
|
||||
|
@ -6721,7 +6742,8 @@
|
|||
"escalade": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
|
||||
"integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw=="
|
||||
"integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
|
||||
"dev": true
|
||||
},
|
||||
"escape-string-regexp": {
|
||||
"version": "4.0.0",
|
||||
|
@ -6791,12 +6813,12 @@
|
|||
}
|
||||
},
|
||||
"eslint": {
|
||||
"version": "8.9.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.9.0.tgz",
|
||||
"integrity": "sha512-PB09IGwv4F4b0/atrbcMFboF/giawbBLVC7fyDamk5Wtey4Jh2K+rYaBhCAbUyEI4QzB1ly09Uglc9iCtFaG2Q==",
|
||||
"version": "8.10.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.10.0.tgz",
|
||||
"integrity": "sha512-tcI1D9lfVec+R4LE1mNDnzoJ/f71Kl/9Cv4nG47jOueCMBrCCKYXr4AUVS7go6mWYGFD4+EoN6+eXSrEbRzXVw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@eslint/eslintrc": "^1.1.0",
|
||||
"@eslint/eslintrc": "^1.2.0",
|
||||
"@humanwhocodes/config-array": "^0.9.2",
|
||||
"ajv": "^6.10.0",
|
||||
"chalk": "^4.0.0",
|
||||
|
@ -7140,7 +7162,8 @@
|
|||
"get-caller-file": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
|
||||
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="
|
||||
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
|
||||
"dev": true
|
||||
},
|
||||
"get-func-name": {
|
||||
"version": "2.0.0",
|
||||
|
@ -7467,14 +7490,14 @@
|
|||
}
|
||||
},
|
||||
"grunt-contrib-jshint": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/grunt-contrib-jshint/-/grunt-contrib-jshint-3.1.1.tgz",
|
||||
"integrity": "sha512-EwMY6L91FqTcMlZTVoDeeq/EZL+7MoFyo1rxIea9sxyv73geVggeE37jcUhNbu5hLbxHE82CGIUqitHuR2/q+g==",
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/grunt-contrib-jshint/-/grunt-contrib-jshint-3.2.0.tgz",
|
||||
"integrity": "sha512-pcXWCSZWfoMSvcV4BwH21TUtLtcX0Ms8IGuOPIcLeXK3fud9KclY7iqMKY94jFx8TxZzh028YYtpR+io8DiEaQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"chalk": "^4.1.0",
|
||||
"chalk": "~4.1.2",
|
||||
"hooker": "^0.2.3",
|
||||
"jshint": "~2.13.0"
|
||||
"jshint": "~2.13.4"
|
||||
}
|
||||
},
|
||||
"grunt-contrib-uglify": {
|
||||
|
@ -8021,7 +8044,8 @@
|
|||
"is-fullwidth-code-point": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
|
||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
|
||||
"dev": true
|
||||
},
|
||||
"is-glob": {
|
||||
"version": "4.0.3",
|
||||
|
@ -8687,9 +8711,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"mocha": {
|
||||
"version": "9.2.0",
|
||||
"resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.0.tgz",
|
||||
"integrity": "sha512-kNn7E8g2SzVcq0a77dkphPsDSN7P+iYkqE0ZsGCYWRsoiKjOt+NvXfaagik8vuDa6W5Zw3qxe8Jfpt5qKf+6/Q==",
|
||||
"version": "9.2.1",
|
||||
"resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.1.tgz",
|
||||
"integrity": "sha512-T7uscqjJVS46Pq1XDXyo9Uvey9gd3huT/DD9cYBb4K2Xc/vbKRPUWK067bxDQRK0yIz6Jxk73IrnimvASzBNAQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@ungap/promise-all-settled": "1.1.2",
|
||||
|
@ -8770,21 +8794,6 @@
|
|||
"requires": {
|
||||
"has-flag": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"yargs": {
|
||||
"version": "16.2.0",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
|
||||
"integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"cliui": "^7.0.2",
|
||||
"escalade": "^3.1.1",
|
||||
"get-caller-file": "^2.0.5",
|
||||
"require-directory": "^2.1.1",
|
||||
"string-width": "^4.2.0",
|
||||
"y18n": "^5.0.5",
|
||||
"yargs-parser": "^20.2.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -9382,7 +9391,8 @@
|
|||
"require-directory": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
|
||||
"integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I="
|
||||
"integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
|
||||
"dev": true
|
||||
},
|
||||
"resolve": {
|
||||
"version": "1.22.0",
|
||||
|
@ -9522,16 +9532,16 @@
|
|||
"dev": true
|
||||
},
|
||||
"sinon": {
|
||||
"version": "12.0.1",
|
||||
"resolved": "https://registry.npmjs.org/sinon/-/sinon-12.0.1.tgz",
|
||||
"integrity": "sha512-iGu29Xhym33ydkAT+aNQFBINakjq69kKO6ByPvTsm3yyIACfyQttRTP03aBP/I8GfhFmLzrnKwNNkr0ORb1udg==",
|
||||
"version": "13.0.1",
|
||||
"resolved": "https://registry.npmjs.org/sinon/-/sinon-13.0.1.tgz",
|
||||
"integrity": "sha512-8yx2wIvkBjIq/MGY1D9h1LMraYW+z1X0mb648KZnKSdvLasvDu7maa0dFaNYdTDczFgbjNw2tOmWdTk9saVfwQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@sinonjs/commons": "^1.8.3",
|
||||
"@sinonjs/fake-timers": "^8.1.0",
|
||||
"@sinonjs/samsam": "^6.0.2",
|
||||
"@sinonjs/fake-timers": "^9.0.0",
|
||||
"@sinonjs/samsam": "^6.1.1",
|
||||
"diff": "^5.0.0",
|
||||
"nise": "^5.1.0",
|
||||
"nise": "^5.1.1",
|
||||
"supports-color": "^7.2.0"
|
||||
}
|
||||
},
|
||||
|
@ -9628,6 +9638,7 @@
|
|||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
|
@ -9638,6 +9649,7 @@
|
|||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^5.0.1"
|
||||
}
|
||||
|
@ -9781,9 +9793,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"uglify-js": {
|
||||
"version": "3.15.1",
|
||||
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.15.1.tgz",
|
||||
"integrity": "sha512-FAGKF12fWdkpvNJZENacOH0e/83eG6JyVQyanIJaBXCN1J11TUQv1T1/z8S+Z0CG0ZPk1nPcreF/c7lrTd0TEQ==",
|
||||
"version": "3.15.2",
|
||||
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.15.2.tgz",
|
||||
"integrity": "sha512-peeoTk3hSwYdoc9nrdiEJk+gx1ALCtTjdYuKSXMTDqq7n1W7dHPqWDdSi+BPL0ni2YMeHD7hKUSdbj3TZauY2A==",
|
||||
"dev": true
|
||||
},
|
||||
"unc-path-regex": {
|
||||
|
@ -9953,6 +9965,7 @@
|
|||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
|
||||
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-styles": "^4.0.0",
|
||||
"string-width": "^4.1.0",
|
||||
|
@ -9993,7 +10006,8 @@
|
|||
"y18n": {
|
||||
"version": "5.0.8",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
|
||||
"integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="
|
||||
"integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
|
||||
"dev": true
|
||||
},
|
||||
"yallist": {
|
||||
"version": "4.0.0",
|
||||
|
@ -10002,24 +10016,18 @@
|
|||
"dev": true
|
||||
},
|
||||
"yargs": {
|
||||
"version": "17.3.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.3.1.tgz",
|
||||
"integrity": "sha512-WUANQeVgjLbNsEmGk20f+nlHgOqzRFpiGWVaBrYGYIGANIIu3lWjoyi0fNlFmJkvfhCZ6BXINe7/W2O2bV4iaA==",
|
||||
"version": "16.2.0",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
|
||||
"integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"cliui": "^7.0.2",
|
||||
"escalade": "^3.1.1",
|
||||
"get-caller-file": "^2.0.5",
|
||||
"require-directory": "^2.1.1",
|
||||
"string-width": "^4.2.3",
|
||||
"string-width": "^4.2.0",
|
||||
"y18n": "^5.0.5",
|
||||
"yargs-parser": "^21.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"yargs-parser": {
|
||||
"version": "21.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.0.tgz",
|
||||
"integrity": "sha512-z9kApYUOCwoeZ78rfRYYWdiU/iNL6mwwYlkkZfJoyMR1xps+NEBX5X7XmRpxkZHhXJ6+Ey00IwKxBBSW9FIjyA=="
|
||||
}
|
||||
"yargs-parser": "^20.2.2"
|
||||
}
|
||||
},
|
||||
"yargs-parser": {
|
||||
|
|
11
package.json
11
package.json
|
@ -38,8 +38,13 @@
|
|||
"bin": {
|
||||
"showdown": "bin/showdown.js"
|
||||
},
|
||||
"files": [
|
||||
"bin",
|
||||
"dist"
|
||||
],
|
||||
"devDependencies": {
|
||||
"chai": "^4.3.4",
|
||||
"chai": "*",
|
||||
"chai-match": "*",
|
||||
"grunt": "^1.4.1",
|
||||
"grunt-contrib-clean": "^2.0.0",
|
||||
"grunt-contrib-concat": "^2.0.0",
|
||||
|
@ -56,10 +61,10 @@
|
|||
"quiet-grunt": "^0.2.0",
|
||||
"semver": "^7.3.0",
|
||||
"semver-sort": "^0.0.4",
|
||||
"sinon": "^12.0.1",
|
||||
"sinon": "*",
|
||||
"source-map-support": "^0.5.20"
|
||||
},
|
||||
"dependencies": {
|
||||
"yargs": "^17.2.1"
|
||||
"commander": "^9.0.0"
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,6 +1,47 @@
|
|||
# Performance Tests for showdown
|
||||
|
||||
|
||||
## [version 2.0.1](https://github.com/showdownjs/showdown/tree/2.0.1)
|
||||
|
||||
### Test Suite: Basic (50 cycles)
|
||||
| test | avgTime | max | min |
|
||||
|:-----|--------:|----:|----:|
|
||||
|Simple "Hello World"|0.387|11.381|0.104|
|
||||
|performance.testfile.md|30.323|64.084|23.327|
|
||||
|
||||
### Test Suite: subParsers (20 cycles)
|
||||
| test | avgTime | max | min |
|
||||
|:-----|--------:|----:|----:|
|
||||
|hashHTMLBlocks|4.436|7.669|2.275|
|
||||
|anchors|0.315|0.977|0.256|
|
||||
|autoLinks|0.083|0.230|0.072|
|
||||
|blockQuotes|4.347|13.862|2.032|
|
||||
|codeBlocks|0.217|0.371|0.203|
|
||||
|codeSpans|0.311|0.734|0.226|
|
||||
|detab|0.062|0.140|0.045|
|
||||
|encodeAmpsAndAngles|0.168|1.440|0.091|
|
||||
|encodeBackslashEscapes|0.073|0.150|0.061|
|
||||
|encodeCode|0.601|1.737|0.526|
|
||||
|escapeSpecialCharsWithinTagAttributes|0.211|0.289|0.195|
|
||||
|githubCodeBlocks|0.169|0.267|0.149|
|
||||
|hashBlock|0.038|0.114|0.034|
|
||||
|hashElement|0.004|0.057|0.001|
|
||||
|hashHTMLSpans|4.053|4.394|3.930|
|
||||
|hashPreCodeTags|0.248|1.891|0.112|
|
||||
|headers|1.273|3.145|1.023|
|
||||
|horizontalRule|0.180|0.418|0.147|
|
||||
|images|0.149|0.402|0.122|
|
||||
|italicsAndBold|0.278|1.041|0.209|
|
||||
|lists|2.979|4.758|2.270|
|
||||
|outdent|0.208|0.427|0.160|
|
||||
|paragraphs|5.247|7.341|4.531|
|
||||
|spanGamut|4.851|10.235|3.512|
|
||||
|strikethrough|0.007|0.101|0.001|
|
||||
|stripLinkDefinitions|1.714|2.990|1.463|
|
||||
|tables|0.008|0.108|0.001|
|
||||
|unescapeSpecialChars|0.012|0.079|0.008|
|
||||
|
||||
|
||||
## [version 1.9.0](https://github.com/showdownjs/showdown/tree/1.9.0)
|
||||
|
||||
### Test Suite: Basic (50 cycles)
|
||||
|
|
353
src/cli/cli.js
353
src/cli/cli.js
|
@ -1,45 +1,324 @@
|
|||
/**
|
||||
* Created by tivie
|
||||
*/
|
||||
'use strict';
|
||||
var fs = require('fs'),
|
||||
json = JSON.parse(fs.readFileSync('package.json', 'utf8')),
|
||||
version = json.version,
|
||||
Command = require('commander').Command,
|
||||
program = new Command(),
|
||||
showdown;
|
||||
|
||||
var yargs = require('yargs');
|
||||
|
||||
yargs
|
||||
.version()
|
||||
.alias('v', 'version')
|
||||
.option('h', {
|
||||
alias: 'help',
|
||||
description: 'Show help'
|
||||
})
|
||||
.option('q', {
|
||||
alias: 'quiet',
|
||||
description: 'Quiet mode. Only print errors',
|
||||
type: 'boolean',
|
||||
default: false
|
||||
})
|
||||
.option('m', {
|
||||
alias: 'mute',
|
||||
description: 'Mute mode. Does not print anything',
|
||||
type: 'boolean',
|
||||
default: false
|
||||
})
|
||||
.usage('Usage: showdown <command> [options]')
|
||||
.demand(1, 'You must provide a valid command')
|
||||
.command('makehtml', 'Converts markdown into html')
|
||||
.example('showdown makehtml -i foo.md -o bar.html', 'Converts \'foo.md\' to \'bar.html\'')
|
||||
.wrap(yargs.terminalWidth());
|
||||
|
||||
var argv = yargs.argv,
|
||||
command = argv._[0];
|
||||
|
||||
if (command === 'makehtml') {
|
||||
require('./makehtml.cmd.js').run();
|
||||
// require shodown. We use conditional loading for each use case
|
||||
if (fs.existsSync('../dist/showdown.js')) {
|
||||
// production. File lives in bin directory
|
||||
showdown = require('../dist/showdown');
|
||||
} else if (fs.existsSync('../../.build/showdown.js')) {
|
||||
// testing envo, uses the concatenated stuff for testing
|
||||
showdown = require('../../.build/showdown.js');
|
||||
} else {
|
||||
yargs.showHelp();
|
||||
// cold testing (manual) of cli.js in the src file. We load the dist file
|
||||
showdown = require('../../dist/showdown');
|
||||
}
|
||||
|
||||
if (argv.help) {
|
||||
yargs.showHelp();
|
||||
program
|
||||
.name('showdown')
|
||||
.description('CLI to Showdownjs markdown parser v' + version)
|
||||
.version(version)
|
||||
.usage('<command> [options]')
|
||||
.option('-q, --quiet', 'Quiet mode. Only print errors')
|
||||
.option('-m, --mute', 'Mute mode. Does not print anything');
|
||||
|
||||
program.command('makehtml')
|
||||
.description('Converts markdown into html')
|
||||
|
||||
.addHelpText('after', '\n\nExamples:')
|
||||
.addHelpText('after', ' showdown makehtml -i Reads from stdin and outputs to stdout')
|
||||
.addHelpText('after', ' showdown makehtml -i foo.md -o bar.html Reads \'foo.md\' and writes to \'bar.html\'')
|
||||
.addHelpText('after', ' showdown makehtml -i --flavor="github" Parses stdin using GFM style')
|
||||
|
||||
.addHelpText('after', '\nNote for windows users:')
|
||||
.addHelpText('after', 'When reading from stdin, use option -u to set the proper encoding or run `chcp 65001` prior to calling showdown cli to set the command line to utf-8')
|
||||
|
||||
.option('-i, --input [file]', 'Input source. Usually a md file. If omitted or empty, reads from stdin. Windows users see note below.', true)
|
||||
.option('-o, --output [file]', 'Output target. Usually a html file. If omitted or empty, writes to stdout', true)
|
||||
.option('-u, --encoding <encoding>', 'Sets the input encoding', 'utf8')
|
||||
.option('-y, --output-encoding <encoding>', 'Sets the output encoding', 'utf8')
|
||||
.option('-a, --append', 'Append data to output instead of overwriting. Ignored if writing to stdout', false)
|
||||
.option('-e, --extensions <extensions...>', 'Load the specified extensions. Should be valid paths to node compatible extensions')
|
||||
.option('-p, --flavor <flavor>', 'Run with a predetermined flavor of options. Default is vanilla', 'vanilla')
|
||||
.option('-c, --config <config...>', 'Enables showdown makehtml parser config options. Overrides flavor')
|
||||
.option('--config-help', 'Shows configuration options for showdown parser')
|
||||
.action(makehtmlCommand);
|
||||
|
||||
program.parse();
|
||||
|
||||
|
||||
//
|
||||
// HELPER FUCNTIONS
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Messenger helper object to the CLI
|
||||
* @param {string} writeMode
|
||||
* @param {boolean} supress
|
||||
* @param {boolean} mute
|
||||
* @constructor
|
||||
*/
|
||||
function Messenger (writeMode, supress, mute) {
|
||||
'use strict';
|
||||
writeMode = writeMode || 'stderr';
|
||||
supress = (!!supress || !!mute);
|
||||
mute = !!mute;
|
||||
this._print = (writeMode === 'stdout') ? console.log : console.error;
|
||||
|
||||
this.errorExit = function (e) {
|
||||
if (!mute) {
|
||||
console.error('ERROR: ' + e.message);
|
||||
console.error('Run \'showdown <command> -h\' for help');
|
||||
}
|
||||
process.exit(1);
|
||||
};
|
||||
|
||||
this.okExit = function () {
|
||||
if (!mute) {
|
||||
this._print('\n');
|
||||
this._print('DONE!');
|
||||
}
|
||||
process.exit(0);
|
||||
};
|
||||
|
||||
this.printMsg = function (msg) {
|
||||
if (supress || mute || !msg) {
|
||||
return;
|
||||
}
|
||||
this._print(msg);
|
||||
};
|
||||
|
||||
this.printError = function (msg) {
|
||||
if (mute) {
|
||||
return;
|
||||
}
|
||||
console.error(msg);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to show Showdown Options
|
||||
*/
|
||||
function showShowdownOptions () {
|
||||
'use strict';
|
||||
var showdownOptions = showdown.getDefaultOptions(false);
|
||||
console.log('\nshowdown makehtml config options:');
|
||||
// show showdown options
|
||||
for (var sopt in showdownOptions) {
|
||||
if (showdownOptions.hasOwnProperty(sopt)) {
|
||||
console.log(' ' + sopt + ':', '[default=' + showdownOptions[sopt].defaultValue + ']',showdownOptions[sopt].describe);
|
||||
}
|
||||
}
|
||||
console.log('\n\nExample: showdown makehtml -c openLinksInNewWindow ghMentions ghMentionsLink="https://google.com"');
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to parse showdown options
|
||||
* @param {{}} configOptions
|
||||
* @param {{}} defaultOptions
|
||||
* @returns {{}}
|
||||
*/
|
||||
function parseShowdownOptions (configOptions, defaultOptions) {
|
||||
'use strict';
|
||||
var shOpt = defaultOptions;
|
||||
|
||||
// first prepare passed options
|
||||
if (configOptions) {
|
||||
for (var i = 0; i < configOptions.length; ++i) {
|
||||
var opt = configOptions[i],
|
||||
key = configOptions[i],
|
||||
val = true;
|
||||
if (/=/.test(opt)) {
|
||||
key = opt.split('=')[0];
|
||||
val = opt.split('=')[1];
|
||||
}
|
||||
shOpt[key] = val;
|
||||
}
|
||||
}
|
||||
return shOpt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads stdin
|
||||
* @returns {string}
|
||||
*/
|
||||
function readFromStdIn (encoding) {
|
||||
'use strict';
|
||||
var size = fs.fstatSync(process.stdin.fd).size;
|
||||
if (size <= 0) {
|
||||
throw new Error('Could not read from stdin, reason: stdin is empty');
|
||||
}
|
||||
encoding = encoding || 'utf8';
|
||||
try {
|
||||
return size > 0 ? fs.readFileSync(process.stdin.fd, encoding).toString() : '';
|
||||
} catch (e) {
|
||||
throw new Error('Could not read from stdin, reason: ' + e.message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads from a file
|
||||
* @param {string} file Filepath to dile
|
||||
* @param {string} encoding Encoding of the file
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
function readFromFile (file, encoding) {
|
||||
'use strict';
|
||||
try {
|
||||
return fs.readFileSync(file, encoding);
|
||||
} catch (err) {
|
||||
throw new Error('Could not read from file ' + file + ', reason: ' + err.message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes to stdout
|
||||
* @param {string} html
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function writeToStdOut (html) {
|
||||
'use strict';
|
||||
if (!process.stdout.write(html)) {
|
||||
throw new Error('Could not write to StdOut');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes to file
|
||||
* @param {string} html HTML to write
|
||||
* @param {string} file Filepath
|
||||
* @param {boolean} append If the result should be appended
|
||||
*/
|
||||
function writeToFile (html, file, append) {
|
||||
'use strict';
|
||||
// If a flag is passed, it means we should append instead of overwriting.
|
||||
// Only works with files, obviously
|
||||
var write = (append) ? fs.appendFileSync : fs.writeFileSync;
|
||||
try {
|
||||
write(file, html);
|
||||
} catch (err) {
|
||||
throw new Error('Could not write to file ' + file + ', readon: ' + err.message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* makehtml command
|
||||
* @param {{}} options
|
||||
* @param {Command} cmd
|
||||
*/
|
||||
function makehtmlCommand (options, cmd) {
|
||||
'use strict';
|
||||
|
||||
// show configuration options for showdown helper if configHelp was passed
|
||||
if (options.configHelp) {
|
||||
showShowdownOptions();
|
||||
return;
|
||||
}
|
||||
|
||||
var quiet = !!(cmd.parent._optionValues.quiet),
|
||||
mute = !!(cmd.parent._optionValues.mute),
|
||||
readMode = (!options.input || options.input === '' || options.input === true) ? 'stdin' : 'file',
|
||||
writeMode = (!options.output || options.output === '' || options.output === true) ? 'stdout' : 'file',
|
||||
msgMode = (writeMode === 'file') ? 'stdout' : 'stderr',
|
||||
// initiate Messenger helper, can maybe be replaced with commanderjs internal stuff
|
||||
messenger = new Messenger(msgMode, quiet, mute),
|
||||
defaultOptions = showdown.getDefaultOptions(true),
|
||||
md, html;
|
||||
|
||||
// deal with flavor first since config flag overrides flavor individual options
|
||||
if (options.flavor) {
|
||||
messenger.printMsg('Enabling flavor ' + options.flavor + '...');
|
||||
defaultOptions = showdown.getFlavorOptions(options.flavor);
|
||||
if (!defaultOptions) {
|
||||
messenger.errorExit(new Error('Flavor ' + options.flavor + ' is not recognised'));
|
||||
return;
|
||||
}
|
||||
messenger.printMsg('OK!');
|
||||
}
|
||||
// store config options in the options.config as an object
|
||||
options.config = parseShowdownOptions(options.config, defaultOptions);
|
||||
|
||||
// print enabled options
|
||||
for (var o in options.config) {
|
||||
if (options.config.hasOwnProperty(o) && options.config[o] === true) {
|
||||
messenger.printMsg('Enabling option ' + o);
|
||||
}
|
||||
}
|
||||
|
||||
// initialize the converter
|
||||
messenger.printMsg('\nInitializing converter...');
|
||||
var converter;
|
||||
try {
|
||||
converter = new showdown.Converter(options.config);
|
||||
} catch (e) {
|
||||
messenger.errorExit(e);
|
||||
return;
|
||||
}
|
||||
messenger.printMsg('OK!');
|
||||
|
||||
// load extensions
|
||||
if (options.extensions) {
|
||||
messenger.printMsg('\nLoading extensions...');
|
||||
for (var i = 0; i < options.extensions.length; ++i) {
|
||||
try {
|
||||
messenger.printMsg(options.extensions[i]);
|
||||
var ext = require(options.extensions[i]);
|
||||
converter.addExtension(ext, options.extensions[i]);
|
||||
messenger.printMsg(options.extensions[i] + ' loaded...');
|
||||
} catch (e) {
|
||||
messenger.printError('Could not load extension ' + options.extensions[i] + '. Reason:');
|
||||
messenger.errorExit(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
messenger.printMsg('...');
|
||||
// read the input
|
||||
messenger.printMsg('Reading data from ' + readMode + '...');
|
||||
|
||||
if (readMode === 'stdin') {
|
||||
try {
|
||||
md = readFromStdIn(options.encoding);
|
||||
} catch (err) {
|
||||
messenger.errorExit(err);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
md = readFromFile(options.input, options.encoding);
|
||||
} catch (err) {
|
||||
messenger.errorExit(err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// process the input
|
||||
messenger.printMsg('Parsing markdown...');
|
||||
html = converter.makeHtml(md);
|
||||
|
||||
// write the output
|
||||
messenger.printMsg('Writing data to ' + writeMode + '...');
|
||||
if (writeMode === 'stdout') {
|
||||
try {
|
||||
writeToStdOut(html);
|
||||
} catch (err) {
|
||||
messenger.errorExit(err);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
writeToFile(html, options.output, options.append);
|
||||
} catch (err) {
|
||||
messenger.errorExit(err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
messenger.okExit();
|
||||
}
|
||||
process.exit(0);
|
||||
|
|
|
@ -1,195 +0,0 @@
|
|||
var yargs = require('yargs'),
|
||||
fs = require('fs'),
|
||||
Messenger = require('./messenger.js'),
|
||||
showdown = require('../../dist/showdown'),
|
||||
showdownOptions = showdown.getDefaultOptions(false);
|
||||
|
||||
yargs.reset()
|
||||
.usage('Usage: showdown makehtml [options]')
|
||||
.example('showdown makehtml -i', 'Reads from stdin and outputs to stdout')
|
||||
.example('showdown makehtml -i foo.md -o bar.html', 'Reads \'foo.md\' and writes to \'bar.html\'')
|
||||
.example('showdown makehtml -i --flavor="github"', 'Parses stdin using GFM style')
|
||||
.version()
|
||||
.alias('v', 'version')
|
||||
.config('c')
|
||||
.alias('c', 'config')
|
||||
.help('h')
|
||||
.alias('h', 'help')
|
||||
.option('i', {
|
||||
alias : 'input',
|
||||
describe: 'Input source. Usually a md file. If omitted or empty, reads from stdin',
|
||||
type: 'string'
|
||||
})
|
||||
.option('o', {
|
||||
alias : 'output',
|
||||
describe: 'Output target. Usually a html file. If omitted or empty, writes to stdout',
|
||||
type: 'string',
|
||||
default: false
|
||||
})
|
||||
.option('u', {
|
||||
alias : 'encoding',
|
||||
describe: 'Input encoding',
|
||||
type: 'string'
|
||||
})
|
||||
.option('a', {
|
||||
alias : 'append',
|
||||
describe: 'Append data to output instead of overwriting',
|
||||
type: 'string',
|
||||
default: false
|
||||
})
|
||||
.option('e', {
|
||||
alias : 'extensions',
|
||||
describe: 'Load the specified extensions. Should be valid paths to node compatible extensions',
|
||||
type: 'array'
|
||||
})
|
||||
.option('p', {
|
||||
alias : 'flavor',
|
||||
describe: 'Run with a predetermined flavor of options. Default is vanilla',
|
||||
type: 'string'
|
||||
})
|
||||
.option('q', {
|
||||
alias: 'quiet',
|
||||
description: 'Quiet mode. Only print errors',
|
||||
type: 'boolean',
|
||||
default: false
|
||||
})
|
||||
.option('m', {
|
||||
alias: 'mute',
|
||||
description: 'Mute mode. Does not print anything',
|
||||
type: 'boolean',
|
||||
default: false
|
||||
});
|
||||
|
||||
// load showdown default options
|
||||
for (var opt in showdownOptions) {
|
||||
if (showdownOptions.hasOwnProperty(opt)) {
|
||||
if (showdownOptions[opt].defaultValue === false) {
|
||||
showdownOptions[opt].default = null;
|
||||
} else {
|
||||
showdownOptions[opt].default = showdownOptions[opt].defaultValue;
|
||||
}
|
||||
yargs.option(opt, showdownOptions[opt]);
|
||||
}
|
||||
}
|
||||
|
||||
function run () {
|
||||
'use strict';
|
||||
var argv = yargs.argv,
|
||||
readMode = (!argv.i || argv.i === '') ? 'stdin' : 'file',
|
||||
writeMode = (!argv.o || argv.o === '') ? 'stdout' : 'file',
|
||||
msgMode = (writeMode === 'file') ? 'stdout' : 'stderr',
|
||||
/**
|
||||
* MSG object
|
||||
* @type {Messenger}
|
||||
*/
|
||||
messenger = new Messenger(msgMode, argv.q, argv.m),
|
||||
read = (readMode === 'stdin') ? readFromStdIn : readFromFile,
|
||||
write = (writeMode === 'stdout') ? writeToStdOut : writeToFile,
|
||||
enc = argv.encoding || 'utf8',
|
||||
flavor = argv.p,
|
||||
append = argv.a || false,
|
||||
options = parseOptions(flavor),
|
||||
converter = new showdown.Converter(options),
|
||||
md, html;
|
||||
|
||||
// Load extensions
|
||||
if (argv.e) {
|
||||
messenger.printMsg('Loading extensions');
|
||||
for (var i = 0; i < argv.e.length; ++i) {
|
||||
try {
|
||||
var ext = require(argv.e[i]);
|
||||
converter.addExtension(ext, argv.e[i]);
|
||||
} catch (e) {
|
||||
messenger.printError('Could not load extension ' + argv.e[i] + '. Reason:');
|
||||
messenger.errorExit(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
messenger.printMsg('...');
|
||||
// read the input
|
||||
messenger.printMsg('Reading data from ' + readMode + '...');
|
||||
md = read(enc);
|
||||
|
||||
// process the input
|
||||
messenger.printMsg('Parsing markdown...');
|
||||
html = converter.makeHtml(md);
|
||||
|
||||
// write the output
|
||||
messenger.printMsg('Writing data to ' + writeMode + '...');
|
||||
write(html, append);
|
||||
messenger.okExit();
|
||||
|
||||
function parseOptions (flavor) {
|
||||
var options = {},
|
||||
flavorOpts = showdown.getFlavorOptions(flavor) || {};
|
||||
|
||||
// if flavor is not undefined, let's tell the user we're loading that preset
|
||||
if (flavor) {
|
||||
messenger.printMsg('Loading ' + flavor + ' flavor.');
|
||||
}
|
||||
|
||||
for (var opt in argv) {
|
||||
if (argv.hasOwnProperty(opt)) {
|
||||
// first we load the default options
|
||||
if (showdownOptions.hasOwnProperty(opt) && showdownOptions[opt].default !== null) {
|
||||
options[opt] = showdownOptions[opt].default;
|
||||
}
|
||||
|
||||
// we now override defaults with flavor, if a flavor was indeed passed
|
||||
if (flavorOpts.hasOwnProperty(opt)) {
|
||||
options[opt] = flavorOpts[opt];
|
||||
}
|
||||
|
||||
// lastly we override with explicit passed options
|
||||
// being careful not to pass CLI specific options, such as -v, -h or --extensions
|
||||
if (showdownOptions.hasOwnProperty(opt)) {
|
||||
if (argv[opt] === true) {
|
||||
messenger.printMsg('Enabling option ' + opt);
|
||||
options[opt] = argv[opt];
|
||||
} else if (argv[opt] === false) {
|
||||
options[opt] = argv[opt];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
function readFromStdIn () {
|
||||
try {
|
||||
var size = fs.fstatSync(process.stdin.fd).size;
|
||||
return size > 0 ? fs.readSync(process.stdin.fd, size)[0] : '';
|
||||
} catch (e) {
|
||||
var err = new Error('Could not read from stdin, reason: ' + e.message);
|
||||
messenger.errorExit(err);
|
||||
}
|
||||
}
|
||||
|
||||
function readFromFile (encoding) {
|
||||
try {
|
||||
return fs.readFileSync(argv.i, encoding);
|
||||
} catch (err) {
|
||||
messenger.errorExit(err);
|
||||
}
|
||||
}
|
||||
|
||||
function writeToStdOut (html) {
|
||||
return process.stdout.write(html);
|
||||
}
|
||||
|
||||
function writeToFile (html, append) {
|
||||
// If a flag is passed, it means we should append instead of overwriting.
|
||||
// Only works with files, obviously
|
||||
var write = (append) ? fs.appendFileSync : fs.writeFileSync;
|
||||
try {
|
||||
write(argv.o, html);
|
||||
} catch (err) {
|
||||
messenger.errorExit(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = exports = {
|
||||
run: run
|
||||
};
|
|
@ -1,40 +0,0 @@
|
|||
function Messenger (writeMode, supress, mute) {
|
||||
'use strict';
|
||||
writeMode = writeMode || 'stderr';
|
||||
supress = (!!supress || !!mute);
|
||||
mute = !!mute;
|
||||
this._print = (writeMode === 'stdout') ? console.log : console.error;
|
||||
|
||||
this.errorExit = function (e) {
|
||||
if (!mute) {
|
||||
console.error('ERROR: ' + e.message);
|
||||
console.error('Run \'showdown <command> -h\' for help');
|
||||
}
|
||||
process.exit(1);
|
||||
};
|
||||
|
||||
this.okExit = function () {
|
||||
if (!mute) {
|
||||
this._print('\n');
|
||||
this._print('DONE!');
|
||||
}
|
||||
process.exit(0);
|
||||
};
|
||||
|
||||
this.printMsg = function (msg) {
|
||||
if (supress || mute || !msg) {
|
||||
return;
|
||||
}
|
||||
this._print(msg);
|
||||
};
|
||||
|
||||
this.printError = function (msg) {
|
||||
if (mute) {
|
||||
return;
|
||||
}
|
||||
console.error(msg);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
module.exports = Messenger;
|
|
@ -98,77 +98,77 @@ function getDefaultOpts (simple) {
|
|||
},
|
||||
smartIndentationFix: {
|
||||
defaultValue: false,
|
||||
description: 'Tries to smartly fix indentation in es6 strings',
|
||||
describe: 'Tries to smartly fix indentation in es6 strings',
|
||||
type: 'boolean'
|
||||
},
|
||||
disableForced4SpacesIndentedSublists: {
|
||||
defaultValue: false,
|
||||
description: 'Disables the requirement of indenting nested sublists by 4 spaces',
|
||||
describe: 'Disables the requirement of indenting nested sublists by 4 spaces',
|
||||
type: 'boolean'
|
||||
},
|
||||
simpleLineBreaks: {
|
||||
defaultValue: false,
|
||||
description: 'Parses simple line breaks as <br> (GFM Style)',
|
||||
describe: 'Parses simple line breaks as <br> (GFM Style)',
|
||||
type: 'boolean'
|
||||
},
|
||||
requireSpaceBeforeHeadingText: {
|
||||
defaultValue: false,
|
||||
description: 'Makes adding a space between `#` and the header text mandatory (GFM Style)',
|
||||
describe: 'Makes adding a space between `#` and the header text mandatory (GFM Style)',
|
||||
type: 'boolean'
|
||||
},
|
||||
ghMentions: {
|
||||
defaultValue: false,
|
||||
description: 'Enables github @mentions',
|
||||
describe: 'Enables github @mentions',
|
||||
type: 'boolean'
|
||||
},
|
||||
ghMentionsLink: {
|
||||
defaultValue: 'https://github.com/{u}',
|
||||
description: 'Changes the link generated by @mentions. Only applies if ghMentions option is enabled.',
|
||||
describe: 'Changes the link generated by @mentions. Only applies if ghMentions option is enabled.',
|
||||
type: 'string'
|
||||
},
|
||||
encodeEmails: {
|
||||
defaultValue: true,
|
||||
description: 'Encode e-mail addresses through the use of Character Entities, transforming ASCII e-mail addresses into its equivalent decimal entities',
|
||||
describe: 'Encode e-mail addresses through the use of Character Entities, transforming ASCII e-mail addresses into its equivalent decimal entities',
|
||||
type: 'boolean'
|
||||
},
|
||||
openLinksInNewWindow: {
|
||||
defaultValue: false,
|
||||
description: 'Open all links in new windows',
|
||||
describe: 'Open all links in new windows',
|
||||
type: 'boolean'
|
||||
},
|
||||
backslashEscapesHTMLTags: {
|
||||
defaultValue: false,
|
||||
description: 'Support for HTML Tag escaping. ex: \<div>foo\</div>',
|
||||
describe: 'Support for HTML Tag escaping. ex: \<div>foo\</div>',
|
||||
type: 'boolean'
|
||||
},
|
||||
emoji: {
|
||||
defaultValue: false,
|
||||
description: 'Enable emoji support. Ex: `this is a :smile: emoji`',
|
||||
describe: 'Enable emoji support. Ex: `this is a :smile: emoji`',
|
||||
type: 'boolean'
|
||||
},
|
||||
underline: {
|
||||
defaultValue: false,
|
||||
description: 'Enable support for underline. Syntax is double or triple underscores: `__underline word__`. With this option enabled, underscores no longer parses into `<em>` and `<strong>`',
|
||||
describe: 'Enable support for underline. Syntax is double or triple underscores: `__underline word__`. With this option enabled, underscores no longer parses into `<em>` and `<strong>`',
|
||||
type: 'boolean'
|
||||
},
|
||||
ellipsis: {
|
||||
defaultValue: true,
|
||||
description: 'Replaces three dots with the ellipsis unicode character',
|
||||
describe: 'Replaces three dots with the ellipsis unicode character',
|
||||
type: 'boolean'
|
||||
},
|
||||
completeHTMLDocument: {
|
||||
defaultValue: false,
|
||||
description: 'Outputs a complete html document, including `<html>`, `<head>` and `<body>` tags',
|
||||
describe: 'Outputs a complete html document, including `<html>`, `<head>` and `<body>` tags',
|
||||
type: 'boolean'
|
||||
},
|
||||
metadata: {
|
||||
defaultValue: false,
|
||||
description: 'Enable support for document metadata (defined at the top of the document between `«««` and `»»»` or between `---` and `---`).',
|
||||
describe: 'Enable support for document metadata (defined at the top of the document between `«««` and `»»»` or between `---` and `---`).',
|
||||
type: 'boolean'
|
||||
},
|
||||
splitAdjacentBlockquotes: {
|
||||
defaultValue: false,
|
||||
description: 'Split adjacent blockquote blocks',
|
||||
describe: 'Split adjacent blockquote blocks',
|
||||
type: 'boolean'
|
||||
}
|
||||
};
|
||||
|
|
|
@ -188,7 +188,7 @@ showdown.subParser = function (name, func) {
|
|||
* Gets or registers an extension
|
||||
* @static
|
||||
* @param {string} name
|
||||
* @param {object|function=} ext
|
||||
* @param {object|object[]|function=} ext
|
||||
* @returns {*}
|
||||
*/
|
||||
showdown.extension = function (name, ext) {
|
||||
|
|
|
@ -1,3 +1,2 @@
|
|||
<h1 id="sometitle">some title</h1>
|
||||
|
||||
<p>Test <strong>bold</strong> and <em>italic</em></p>
|
||||
|
|
14
test/mocks/mock-extension.js
Normal file
14
test/mocks/mock-extension.js
Normal file
|
@ -0,0 +1,14 @@
|
|||
var showdown = require('../../.build/showdown.js');
|
||||
|
||||
var ext = {
|
||||
type: 'lang',
|
||||
regex: /foo/g,
|
||||
replace: 'bar'
|
||||
};
|
||||
|
||||
showdown.extension('mockextension', function () {
|
||||
'use strict';
|
||||
return [ext];
|
||||
});
|
||||
|
||||
module.exports = ext;
|
|
@ -1,18 +0,0 @@
|
|||
/*
|
||||
var semver = require('semver'),
|
||||
cmd = 'node bin/showdown.js';
|
||||
|
||||
describe('showdown cli', function () {
|
||||
'use strict';
|
||||
if (semver.gt(process.versions.node, '0.12.0')) {
|
||||
var execSync = require('child_process').execSync;
|
||||
it('basic stdin stdout', function () {
|
||||
var otp = execSync(cmd + ' makehtml -q', {
|
||||
encoding: 'utf8',
|
||||
input: '**foo**'
|
||||
});
|
||||
otp.trim().should.equal('<p><strong>foo</strong></p>');
|
||||
});
|
||||
}
|
||||
});
|
||||
*/
|
293
test/node/testsuite.cli.js
Normal file
293
test/node/testsuite.cli.js
Normal file
|
@ -0,0 +1,293 @@
|
|||
var fs = require('fs'),
|
||||
path = require('path'),
|
||||
chai = require('chai'),
|
||||
expect = chai.expect,
|
||||
chaiMatch = require('chai-match'),
|
||||
execSync = require('child_process').execSync,
|
||||
spawnSync = require('child_process').spawnSync,
|
||||
cmd = 'node src/cli/cli.js',
|
||||
packageJson = JSON.parse(fs.readFileSync('package.json', 'utf8'));
|
||||
|
||||
require('sinon');
|
||||
chai.should();
|
||||
chai.use(chaiMatch);
|
||||
|
||||
/**
|
||||
* Spawns a CLI process synchrously
|
||||
* @param {string|null} command
|
||||
* @param {string[]} args
|
||||
* @param {{}} [options]
|
||||
* @returns {{output: *, stdout: string, stderr: string, status: number}}
|
||||
*/
|
||||
function spawnCLI (command, args, options) {
|
||||
'use strict';
|
||||
var nargs = ['src/cli/cli.js'];
|
||||
if (command) { nargs.push(command);}
|
||||
args = nargs.concat(args);
|
||||
var otp = spawnSync('node', args, options),
|
||||
stdout = otp.stdout.toString(),
|
||||
stderr = otp.stderr.toString(),
|
||||
output = otp.output[0],
|
||||
status = otp.status;
|
||||
|
||||
return {stdout: stdout, stderr: stderr, output: output, status: status};
|
||||
}
|
||||
|
||||
describe('showdown cli', function () {
|
||||
'use strict';
|
||||
|
||||
describe('without commands', function () {
|
||||
|
||||
it('should display help if no commands are specified', function () {
|
||||
var proc = spawnCLI(null, [], {});
|
||||
proc.status.should.equal(1);
|
||||
proc.stderr.should.contain('CLI to Showdownjs markdown parser');
|
||||
proc.stderr.should.contain('Usage:');
|
||||
proc.stderr.should.contain('Options:');
|
||||
proc.stderr.should.contain('Commands:');
|
||||
proc.stdout.should.equal('');
|
||||
});
|
||||
|
||||
describe('-h', function () {
|
||||
it('should display help', function () {
|
||||
var proc = spawnCLI(null, ['-h'], {});
|
||||
proc.status.should.equal(0);
|
||||
proc.stdout.should.contain('CLI to Showdownjs markdown parser');
|
||||
proc.stdout.should.contain('Usage:');
|
||||
proc.stdout.should.contain('Options:');
|
||||
proc.stdout.should.contain('Commands:');
|
||||
proc.stderr.should.equal('');
|
||||
});
|
||||
});
|
||||
|
||||
describe('-v', function () {
|
||||
it('should display version', function () {
|
||||
var proc = spawnCLI(null, ['-V'], {});
|
||||
proc.status.should.equal(0);
|
||||
proc.stdout.should.match(/^\d{1,2}\.\d{1,3}\.\d{1,3}/);
|
||||
proc.stdout.should.match(/^(\d{1,2}\.\d{1,3}\.\d{1,3})/).and.capture(0).equals(packageJson.version);
|
||||
proc.stderr.should.equal('');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('makehtml command', function () {
|
||||
|
||||
describe('makehtml without flags', function () {
|
||||
it('should read from stdin and output to stdout', function () {
|
||||
var proc = spawnCLI('makehtml', [], {
|
||||
input: '**foo**',
|
||||
encoding: 'utf-8'
|
||||
});
|
||||
proc.status.should.equal(0);
|
||||
proc.stdout.should.equal('<p><strong>foo</strong></p>');
|
||||
proc.stderr.should.not.equal('');
|
||||
});
|
||||
});
|
||||
|
||||
describe('makehtml -p', function () {
|
||||
|
||||
it('should enable a flavor', function () {
|
||||
var proc = spawnCLI('makehtml', ['-p', 'github'], {
|
||||
input: 'this is a :smile:', // test the emoji option as a proxy
|
||||
encoding: 'utf-8'
|
||||
});
|
||||
proc.status.should.equal(0);
|
||||
proc.stderr.should.contain('Enabling flavor github...');
|
||||
proc.stdout.should.equal('<p>this is a 😄</p>');
|
||||
//'Here in London'.should.match(/(here|there) in (\w+)/i).and.capture(1).equals('London');
|
||||
});
|
||||
|
||||
it('should give an error if a flavor is not recognised', function () {
|
||||
var proc = spawnCLI('makehtml', ['-p', 'foobar'], {
|
||||
input: '**foo**',
|
||||
encoding: 'utf-8'
|
||||
});
|
||||
proc.status.should.equal(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('makehtml -c', function () {
|
||||
it('should not parse emoji if config option is not passed', function () {
|
||||
var proc = spawnCLI('makehtml', [], {
|
||||
input: 'this is a :smile:',
|
||||
encoding: 'utf-8'
|
||||
});
|
||||
proc.status.should.equal(0);
|
||||
proc.stderr.should.not.contain('Enabling option emoji');
|
||||
proc.stdout.should.equal('<p>this is a :smile:</p>');
|
||||
});
|
||||
|
||||
it('should enable a showdown option', function () {
|
||||
var proc = spawnCLI('makehtml', ['-c', 'emoji'], {
|
||||
input: 'this is a :smile:',
|
||||
encoding: 'utf-8'
|
||||
});
|
||||
proc.status.should.equal(0);
|
||||
proc.stderr.should.contain('Enabling option emoji');
|
||||
proc.stdout.should.equal('<p>this is a 😄</p>');
|
||||
});
|
||||
|
||||
it('should ignore unrecognized options', function () {
|
||||
var proc = spawnCLI('makehtml', ['-c', 'foobar'], {
|
||||
input: 'foo',
|
||||
encoding: 'utf-8'
|
||||
});
|
||||
proc.status.should.equal(0);
|
||||
proc.stderr.should.contain('Enabling option foobar');
|
||||
proc.stdout.should.equal('<p>foo</p>');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('makehtml -m', function () {
|
||||
|
||||
it('should mute information', function () {
|
||||
var proc = spawnCLI('makehtml', ['-m', '-i'], {input: '**foo**'});
|
||||
proc.status.should.equal(0);
|
||||
expect(proc.output).to.be.null; // jshint ignore:line
|
||||
proc.stdout.should.equal('<p><strong>foo</strong></p>');
|
||||
proc.stderr.should.equal('');
|
||||
});
|
||||
|
||||
it('should mute everything, even errors', function () {
|
||||
var proc = spawnCLI('makehtml', ['-m', '-i']);
|
||||
proc.status.should.equal(1);
|
||||
expect(proc.output).to.be.null; // jshint ignore:line
|
||||
proc.stdout.should.equal('');
|
||||
proc.stderr.should.equal('');
|
||||
});
|
||||
|
||||
it('should not mute parsed html', function () {
|
||||
var proc = spawnCLI('makehtml', ['-m', '-i'], {
|
||||
input: '**foo**',
|
||||
encoding: 'utf-8'
|
||||
});
|
||||
proc.status.should.equal(0);
|
||||
proc.stdout.should.equal('<p><strong>foo</strong></p>');
|
||||
proc.stderr.should.equal('');
|
||||
});
|
||||
});
|
||||
|
||||
describe('makehtml -q', function () {
|
||||
|
||||
it('should not display information', function () {
|
||||
var proc = spawnCLI('makehtml', ['-q', '-i'], {input: '**foo**'});
|
||||
proc.status.should.equal(0);
|
||||
expect(proc.output).to.be.null; // jshint ignore:line
|
||||
proc.stdout.should.equal('<p><strong>foo</strong></p>');
|
||||
proc.stderr.should.match(/^\s*DONE!\s*$/);
|
||||
});
|
||||
|
||||
it('should display errors', function () {
|
||||
var proc = spawnCLI('makehtml', ['-q', '-i']);
|
||||
proc.status.should.equal(1);
|
||||
expect(proc.output).to.be.null; // jshint ignore:line
|
||||
proc.stdout.should.equal('');
|
||||
proc.stderr.should.match(/^ERROR:/);
|
||||
});
|
||||
|
||||
it('should not mute parsed html', function () {
|
||||
var proc = spawnCLI('makehtml', ['-q', '-i'], {
|
||||
input: '**foo**',
|
||||
encoding: 'utf-8'
|
||||
});
|
||||
proc.status.should.equal(0);
|
||||
proc.stdout.should.equal('<p><strong>foo</strong></p>');
|
||||
proc.stderr.should.match(/^\s*DONE!\s*$/);
|
||||
});
|
||||
});
|
||||
|
||||
describe('makehtml -i -o', function () {
|
||||
it('should read from stdin and output to stdout', function () {
|
||||
var proc = spawnCLI('makehtml', ['-i', '-o'], {
|
||||
input: '**foo**',
|
||||
encoding: 'utf-8'
|
||||
});
|
||||
proc.status.should.equal(0);
|
||||
proc.stdout.should.equal('<p><strong>foo</strong></p>');
|
||||
proc.stderr.should.not.equal('');
|
||||
});
|
||||
});
|
||||
|
||||
describe('makehtml -i <file> -o', function () {
|
||||
it('should read from a file and output to stdout', function () {
|
||||
var expectedOtp = fs.readFileSync('test/cli/basic.html', 'utf8').toString().trim(),
|
||||
proc = spawnCLI('makehtml', ['-i', 'test/cli/basic.md'], {encoding: 'utf-8'});
|
||||
|
||||
proc.status.should.equal(0);
|
||||
proc.stdout.should.equal(expectedOtp);
|
||||
proc.stderr.should.not.equal('');
|
||||
});
|
||||
});
|
||||
|
||||
describe('makehtml -i -o <file>', function () {
|
||||
it('should read from stdin and output to a file', function () {
|
||||
execSync(cmd + ' makehtml -m -i -o .build/io1.html', {
|
||||
encoding: 'utf8',
|
||||
input: '**foo**'
|
||||
});
|
||||
var otp = fs.readFileSync('.build/io1.html', 'utf8').toString().trim(),
|
||||
expectedOtp = '<p><strong>foo</strong></p>';
|
||||
|
||||
otp.trim().should.equal(expectedOtp);
|
||||
});
|
||||
});
|
||||
|
||||
describe('makehtml -i <file> -o <file>', function () {
|
||||
it('should read from a file and output to a file', function () {
|
||||
var expectedOtp = fs.readFileSync('test/cli/basic.html', 'utf8').toString().trim(),
|
||||
proc = spawnCLI('makehtml', ['-i', 'test/cli/basic.md', '-o', '.build/io2.html'], {encoding: 'utf-8'}),
|
||||
otp = fs.readFileSync('.build/io2.html', 'utf8').toString().trim();
|
||||
|
||||
otp.trim().should.equal(expectedOtp);
|
||||
proc.stdout.should.not.equal(expectedOtp);
|
||||
proc.stderr.should.equal('');
|
||||
proc.status.should.equal(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('makehtml -a', function () {
|
||||
it('should read from stdin and append to a file', function () {
|
||||
fs.writeFileSync('.build/io3.html', '<p>foo</p>');
|
||||
|
||||
var expectedOtp = '<p>foo</p><p><strong>foo</strong></p>',
|
||||
proc = spawnCLI('makehtml', ['-i', '-o', '.build/io3.html', '-a'], {
|
||||
encoding: 'utf8',
|
||||
input: '**foo**'
|
||||
}),
|
||||
otp = fs.readFileSync('.build/io3.html', 'utf8').toString().trim();
|
||||
|
||||
proc.status.should.equal(0);
|
||||
otp.trim().should.equal(expectedOtp);
|
||||
// since the output is to a file, messages are logged to stdout
|
||||
proc.stdout.should.not.equal(expectedOtp);
|
||||
// stderr should be empty
|
||||
proc.stderr.should.equal('');
|
||||
});
|
||||
|
||||
it('should ignore -a flag if -o <file> is missing', function () {
|
||||
|
||||
var expectedOtp = '<p><strong>foo</strong></p>',
|
||||
proc = spawnCLI('makehtml', ['-a'], {encoding: 'utf8', input: '**foo**'});
|
||||
proc.status.should.equal(0);
|
||||
proc.stderr.should.not.equal('');
|
||||
proc.stdout.should.equal(expectedOtp);
|
||||
});
|
||||
});
|
||||
|
||||
describe('makehtml -e', function () {
|
||||
it('should load the extension', function () {
|
||||
var expectedOtp = '<p><strong>bar</strong></p>',
|
||||
extPath = path.resolve(__dirname + '/../mocks/mock-extension.js'),
|
||||
proc = spawnCLI('makehtml', ['-i', '-o', '-e', extPath], {
|
||||
encoding: 'utf8',
|
||||
input: '**foo**'
|
||||
});
|
||||
proc.status.should.equal(0, 'Process exited with error state');
|
||||
proc.stdout.trim().should.equal(expectedOtp);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
});
|
|
@ -3,6 +3,7 @@ require('chai').should();
|
|||
var expect = require('chai').expect,
|
||||
showdown = require('../bootstrap').showdown;
|
||||
|
||||
|
||||
describe('showdown.options', function () {
|
||||
'use strict';
|
||||
|
||||
|
@ -34,21 +35,37 @@ describe('showdown.extension()', function () {
|
|||
return extObjMock;
|
||||
};
|
||||
|
||||
describe('should register', function () {
|
||||
it('an extension object', function () {
|
||||
describe('file loading', function () {
|
||||
|
||||
beforeEach(function () {
|
||||
this.extension = require('../mocks/mock-extension');
|
||||
});
|
||||
|
||||
it('should register an extension from a file', function () {
|
||||
showdown.extension('mockextension').should.be.an('array');
|
||||
showdown.extension('mockextension').should.eql([this.extension]);
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
showdown.resetExtensions();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
describe('objects', function () {
|
||||
it('should register an extension object', function () {
|
||||
showdown.extension('foo', extObjMock);
|
||||
showdown.extension('foo').should.eql([extObjMock]);
|
||||
showdown.resetExtensions();
|
||||
});
|
||||
|
||||
it('an extension function', function () {
|
||||
showdown.extension('foo', extObjFunc);
|
||||
showdown.extension('foo').should.eql([extObjMock]);
|
||||
showdown.resetExtensions();
|
||||
it('should register an extension function', function () {
|
||||
showdown.extension('bar', extObjFunc);
|
||||
showdown.extension('bar').should.eql([extObjMock]);
|
||||
});
|
||||
|
||||
it('a listener extension', function () {
|
||||
showdown.extension('foo', {
|
||||
it('should register a listener extension', function () {
|
||||
showdown.extension('baz', {
|
||||
type: 'listener',
|
||||
listeners: {
|
||||
foo: function (name, txt) {
|
||||
|
@ -56,19 +73,16 @@ describe('showdown.extension()', function () {
|
|||
}
|
||||
}
|
||||
});
|
||||
showdown.resetExtensions();
|
||||
});
|
||||
});
|
||||
|
||||
describe('should refuse to register', function () {
|
||||
it('a generic object', function () {
|
||||
it('should refuse to register a generic object', function () {
|
||||
var fn = function () {
|
||||
showdown.extension('foo', {});
|
||||
};
|
||||
expect(fn).to.throw();
|
||||
});
|
||||
|
||||
it('an extension with invalid type', function () {
|
||||
it('should refuse to register an extension with invalid type', function () {
|
||||
var fn = function () {
|
||||
showdown.extension('foo', {
|
||||
type: 'foo'
|
||||
|
@ -77,7 +91,7 @@ describe('showdown.extension()', function () {
|
|||
expect(fn).to.throw(/type .+? is not recognized\. Valid values: "lang\/language", "output\/html" or "listener"/);
|
||||
});
|
||||
|
||||
it('an extension without regex or filter', function () {
|
||||
it('should refuse to register an extension without regex or filter', function () {
|
||||
var fn = function () {
|
||||
showdown.extension('foo', {
|
||||
type: 'lang'
|
||||
|
@ -86,7 +100,7 @@ describe('showdown.extension()', function () {
|
|||
expect(fn).to.throw(/extensions must define either a "regex" property or a "filter" method/);
|
||||
});
|
||||
|
||||
it('a listener extension without a listeners property', function () {
|
||||
it('should refuse to register a listener extension without a listeners property', function () {
|
||||
var fn = function () {
|
||||
showdown.extension('foo', {
|
||||
type: 'listener'
|
||||
|
@ -94,7 +108,13 @@ describe('showdown.extension()', function () {
|
|||
};
|
||||
expect(fn).to.throw(/Extensions of type "listener" must have a property called "listeners"/);
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
showdown.resetExtensions();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('showdown.getAllExtensions()', function () {
|
Loading…
Reference in New Issue
Block a user