diff --git a/.gitignore b/.gitignore
index fc156669..1406785e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,5 +3,5 @@ node_modules/
tmp/
*.log
.idea/
-coverage/
+.nyc_output/
highlight_alias.json
diff --git a/.npmignore b/.npmignore
deleted file mode 100644
index 23f6a506..00000000
--- a/.npmignore
+++ /dev/null
@@ -1,9 +0,0 @@
-test/
-tmp/
-coverage/
-*.log
-.jshintrc
-.travis.yml
-gulpfile.js
-.idea/
-appveyor.yml
diff --git a/.travis.yml b/.travis.yml
index 52672917..42cf8d2c 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -8,16 +8,14 @@ cache:
- node_modules
node_js:
- - "6"
+ - "8"
+ - "10"
- "node"
script:
- # For older versions of npm (ie. the one bundled with Node 6), we need to manually run `prepare`
- # to build the project. You can still install and consume the package without any issue.
- - if [[ "$TRAVIS_NODE_VERSION" == "6" ]]; then npm run prepare; fi
- npm run eslint
- npm run test-cov
after_script:
- npm install coveralls
- - cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js
+ - nyc report --reporter=text-lcov | coveralls
diff --git a/CHANGELOG.md b/CHANGELOG.md
deleted file mode 100644
index 9389aa1d..00000000
--- a/CHANGELOG.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# Next
-
-- **[Fix]** Remove postinstall step, fixes installations issues for some systems. [#24](https://github.com/hexojs/hexo-util/issues/24)
diff --git a/README.md b/README.md
index b536f549..112d5ef2 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,10 @@
# hexo-util
-[![Build Status](https://travis-ci.org/hexojs/hexo-util.svg?branch=master)](https://travis-ci.org/hexojs/hexo-util) [![NPM version](https://badge.fury.io/js/hexo-util.svg)](http://badge.fury.io/js/hexo-util) [![Coverage Status](https://coveralls.io/repos/hexojs/hexo-util/badge.svg?branch=master&service=github)](https://coveralls.io/github/hexojs/hexo-util?branch=master) [![dependencies Status](https://david-dm.org/hexojs/hexo-util/status.svg)](https://david-dm.org/hexojs/hexo-util) [![devDependencies Status](https://david-dm.org/hexojs/hexo-util/dev-status.svg)](https://david-dm.org/hexojs/hexo-util?type=dev)
+[![Build Status](https://travis-ci.org/hexojs/hexo-util.svg?branch=master)](https://travis-ci.org/hexojs/hexo-util)
+[![NPM version](https://badge.fury.io/js/hexo-util.svg)](https://www.npmjs.com/package/hexo-util)
+[![Coverage Status](https://coveralls.io/repos/hexojs/hexo-util/badge.svg?branch=master&service=github)](https://coveralls.io/github/hexojs/hexo-util?branch=master)
+[![dependencies Status](https://david-dm.org/hexojs/hexo-util/status.svg)](https://david-dm.org/hexojs/hexo-util)
+[![devDependencies Status](https://david-dm.org/hexojs/hexo-util/dev-status.svg)](https://david-dm.org/hexojs/hexo-util?type=dev)
Utilities for [Hexo].
@@ -67,6 +71,7 @@ hash('123456');
```
### HashStream()
+**\[deprecated\]** use `createSha1Hash()`.
Generates SHA1 hash with a transform stream.
@@ -80,6 +85,18 @@ fs.createReadStream('/path/to/file')
});
```
+### createSha1Hash()
+return SHA1 hash object.
+ This is the same as calling `createHash('utf8')` in the node.js native module crypto.
+ ``` js
+const sha1 = createSha1Hash();
+ fs.createReadStream('/path/to/file')
+ .pipe(sha1)
+ .on('finish', () => {
+ console.log(sha1.read());
+ });
+```
+
### highlight(str, [options])
Syntax highlighting for a code block.
diff --git a/appveyor.yml b/appveyor.yml
new file mode 100644
index 00000000..0846e741
--- /dev/null
+++ b/appveyor.yml
@@ -0,0 +1,36 @@
+# Fix line endings in Windows. (runs before repo cloning)
+init:
+ - git config --global core.autocrlf input
+
+# Test against these versions of Node.js.
+environment:
+ matrix:
+ - nodejs_version: "8"
+ - nodejs_version: "10"
+ - nodejs_version: "12"
+
+matrix:
+ fast_finish: true
+
+# Install scripts. (runs after repo cloning)
+install:
+ - ps: Install-Product node $env:nodejs_version
+ - npm install -g npm
+ - npm install
+
+cache:
+ - node_modules -> package.json
+
+# Post-install test scripts.
+test_script:
+ # Output useful info for debugging.
+ - node --version
+ - npm --version
+ # Run tests
+ - npm test
+
+# Don't actually build.
+build: off
+
+# Set build version format here instead of in the admin panel.
+version: "{build}"
diff --git a/lib/cache_stream.js b/lib/cache_stream.js
index 640d9412..91e65124 100644
--- a/lib/cache_stream.js
+++ b/lib/cache_stream.js
@@ -1,6 +1,6 @@
'use strict';
-var Transform = require('stream').Transform;
+const { Transform } = require('stream');
function CacheStream() {
Transform.call(this);
@@ -11,7 +11,7 @@ function CacheStream() {
require('util').inherits(CacheStream, Transform);
CacheStream.prototype._transform = function(chunk, enc, callback) {
- var buf = chunk instanceof Buffer ? chunk : Buffer.from(chunk, enc);
+ const buf = chunk instanceof Buffer ? chunk : Buffer.from(chunk, enc);
this._cache.push(buf);
this.push(buf);
diff --git a/lib/camel_case_keys.js b/lib/camel_case_keys.js
index 40b0badf..55e04f3e 100644
--- a/lib/camel_case_keys.js
+++ b/lib/camel_case_keys.js
@@ -1,8 +1,6 @@
'use strict';
-var camelCase = require('camel-case');
-
-var rPrefixUnderscore = /^(_+)/;
+const camelCase = require('camel-case');
function getter(key) {
return function() {
@@ -16,31 +14,37 @@ function setter(key) {
};
}
+function toCamelCase(str) {
+ let prefixLength = -1;
+
+ while (str[++prefixLength] === '_');
+
+ if (!prefixLength) {
+ return camelCase(str);
+ }
+ return str.substring(0, prefixLength) + camelCase(str.substring(prefixLength));
+}
+
function camelCaseKeys(obj) {
if (typeof obj !== 'object') throw new TypeError('obj must be an object!');
- var keys = Object.keys(obj);
- var result = {};
+ const keys = Object.keys(obj);
+ const { length } = keys;
+ const result = {};
- for (var i = 0, len = keys.length; i < len; i++) {
- var key = keys[i];
- var value = obj[key];
- var match = key.match(rPrefixUnderscore);
- var newKey;
+ for (let i = 0; i < length; i++) {
+ const oldKey = keys[i];
+ const newKey = toCamelCase(oldKey);
- if (match) {
- var underscore = match[1];
- newKey = underscore + camelCase(key.substring(underscore.length));
- } else {
- newKey = camelCase(key);
- }
+ result[newKey] = obj[oldKey];
- if (newKey === key) {
- result[key] = value;
- } else {
- result[newKey] = value;
- result.__defineGetter__(key, getter(newKey));
- result.__defineSetter__(key, setter(newKey));
+ if (newKey !== oldKey) {
+ Object.defineProperty(result, oldKey, {
+ get: getter(newKey),
+ set: setter(newKey),
+ configurable: true,
+ enumerable: true
+ });
}
}
diff --git a/lib/color.js b/lib/color.js
new file mode 100644
index 00000000..0cae20d0
--- /dev/null
+++ b/lib/color.js
@@ -0,0 +1,336 @@
+'use strict';
+
+// https://github.com/imathis/hsl-picker/blob/master/assets/javascripts/modules/color.coffee
+const rHex3 = /^#[0-9a-f]{3}$/;
+const rHex6 = /^#[0-9a-f]{6}$/;
+const rRGB = /^rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,?\s*(0?\.?\d+)?\s*\)$/;
+const rHSL = /^hsla?\(\s*(\d{1,3})\s*,\s*(\d{1,3})%\s*,\s*(\d{1,3})%\s*,?\s*(0?\.?\d+)?\s*\)$/;
+
+// https://www.w3.org/TR/css3-color/#svg-color
+const colorNames = {
+ aliceblue: {r: 240, g: 248, b: 255, a: 1},
+ antiquewhite: {r: 250, g: 235, b: 215, a: 1},
+ aqua: {r: 0, g: 255, b: 255, a: 1},
+ aquamarine: {r: 127, g: 255, b: 212, a: 1},
+ azure: {r: 240, g: 255, b: 255, a: 1},
+ beige: {r: 245, g: 245, b: 220, a: 1},
+ bisque: {r: 255, g: 228, b: 196, a: 1},
+ black: {r: 0, g: 0, b: 0, a: 1},
+ blanchedalmond: {r: 255, g: 235, b: 205, a: 1},
+ blue: {r: 0, g: 0, b: 255, a: 1},
+ blueviolet: {r: 138, g: 43, b: 226, a: 1},
+ brown: {r: 165, g: 42, b: 42, a: 1},
+ burlywood: {r: 222, g: 184, b: 135, a: 1},
+ cadetblue: {r: 95, g: 158, b: 160, a: 1},
+ chartreuse: {r: 127, g: 255, b: 0, a: 1},
+ chocolate: {r: 210, g: 105, b: 30, a: 1},
+ coral: {r: 255, g: 127, b: 80, a: 1},
+ cornflowerblue: {r: 100, g: 149, b: 237, a: 1},
+ cornsilk: {r: 255, g: 248, b: 220, a: 1},
+ crimson: {r: 220, g: 20, b: 60, a: 1},
+ cyan: {r: 0, g: 255, b: 255, a: 1},
+ darkblue: {r: 0, g: 0, b: 139, a: 1},
+ darkcyan: {r: 0, g: 139, b: 139, a: 1},
+ darkgoldenrod: {r: 184, g: 134, b: 11, a: 1},
+ darkgray: {r: 169, g: 169, b: 169, a: 1},
+ darkgreen: {r: 0, g: 100, b: 0, a: 1},
+ darkgrey: {r: 169, g: 169, b: 169, a: 1},
+ darkkhaki: {r: 189, g: 183, b: 107, a: 1},
+ darkmagenta: {r: 139, g: 0, b: 139, a: 1},
+ darkolivegreen: {r: 85, g: 107, b: 47, a: 1},
+ darkorange: {r: 255, g: 140, b: 0, a: 1},
+ darkorchid: {r: 153, g: 50, b: 204, a: 1},
+ darkred: {r: 139, g: 0, b: 0, a: 1},
+ darksalmon: {r: 233, g: 150, b: 122, a: 1},
+ darkseagreen: {r: 143, g: 188, b: 143, a: 1},
+ darkslateblue: {r: 72, g: 61, b: 139, a: 1},
+ darkslategray: {r: 47, g: 79, b: 79, a: 1},
+ darkslategrey: {r: 47, g: 79, b: 79, a: 1},
+ darkturquoise: {r: 0, g: 206, b: 209, a: 1},
+ darkviolet: {r: 148, g: 0, b: 211, a: 1},
+ deeppink: {r: 255, g: 20, b: 147, a: 1},
+ deepskyblue: {r: 0, g: 191, b: 255, a: 1},
+ dimgray: {r: 105, g: 105, b: 105, a: 1},
+ dimgrey: {r: 105, g: 105, b: 105, a: 1},
+ dodgerblue: {r: 30, g: 144, b: 255, a: 1},
+ firebrick: {r: 178, g: 34, b: 34, a: 1},
+ floralwhite: {r: 255, g: 250, b: 240, a: 1},
+ forestgreen: {r: 34, g: 139, b: 34, a: 1},
+ fuchsia: {r: 255, g: 0, b: 255, a: 1},
+ gainsboro: {r: 220, g: 220, b: 220, a: 1},
+ ghostwhite: {r: 248, g: 248, b: 255, a: 1},
+ gold: {r: 255, g: 215, b: 0, a: 1},
+ goldenrod: {r: 218, g: 165, b: 32, a: 1},
+ gray: {r: 128, g: 128, b: 128, a: 1},
+ green: {r: 0, g: 128, b: 0, a: 1},
+ greenyellow: {r: 173, g: 255, b: 47, a: 1},
+ grey: {r: 128, g: 128, b: 128, a: 1},
+ honeydew: {r: 240, g: 255, b: 240, a: 1},
+ hotpink: {r: 255, g: 105, b: 180, a: 1},
+ indianred: {r: 205, g: 92, b: 92, a: 1},
+ indigo: {r: 75, g: 0, b: 130, a: 1},
+ ivory: {r: 255, g: 255, b: 240, a: 1},
+ khaki: {r: 240, g: 230, b: 140, a: 1},
+ lavender: {r: 230, g: 230, b: 250, a: 1},
+ lavenderblush: {r: 255, g: 240, b: 245, a: 1},
+ lawngreen: {r: 124, g: 252, b: 0, a: 1},
+ lemonchiffon: {r: 255, g: 250, b: 205, a: 1},
+ lightblue: {r: 173, g: 216, b: 230, a: 1},
+ lightcoral: {r: 240, g: 128, b: 128, a: 1},
+ lightcyan: {r: 224, g: 255, b: 255, a: 1},
+ lightgoldenrodyellow: {r: 250, g: 250, b: 210, a: 1},
+ lightgray: {r: 211, g: 211, b: 211, a: 1},
+ lightgreen: {r: 144, g: 238, b: 144, a: 1},
+ lightgrey: {r: 211, g: 211, b: 211, a: 1},
+ lightpink: {r: 255, g: 182, b: 193, a: 1},
+ lightsalmon: {r: 255, g: 160, b: 122, a: 1},
+ lightseagreen: {r: 32, g: 178, b: 170, a: 1},
+ lightskyblue: {r: 135, g: 206, b: 250, a: 1},
+ lightslategray: {r: 119, g: 136, b: 153, a: 1},
+ lightslategrey: {r: 119, g: 136, b: 153, a: 1},
+ lightsteelblue: {r: 176, g: 196, b: 222, a: 1},
+ lightyellow: {r: 255, g: 255, b: 224, a: 1},
+ lime: {r: 0, g: 255, b: 0, a: 1},
+ limegreen: {r: 50, g: 205, b: 50, a: 1},
+ linen: {r: 250, g: 240, b: 230, a: 1},
+ magenta: {r: 255, g: 0, b: 255, a: 1},
+ maroon: {r: 128, g: 0, b: 0, a: 1},
+ mediumaquamarine: {r: 102, g: 205, b: 170, a: 1},
+ mediumblue: {r: 0, g: 0, b: 205, a: 1},
+ mediumorchid: {r: 186, g: 85, b: 211, a: 1},
+ mediumpurple: {r: 147, g: 112, b: 219, a: 1},
+ mediumseagreen: {r: 60, g: 179, b: 113, a: 1},
+ mediumslateblue: {r: 123, g: 104, b: 238, a: 1},
+ mediumspringgreen: {r: 0, g: 250, b: 154, a: 1},
+ mediumturquoise: {r: 72, g: 209, b: 204, a: 1},
+ mediumvioletred: {r: 199, g: 21, b: 133, a: 1},
+ midnightblue: {r: 25, g: 25, b: 112, a: 1},
+ mintcream: {r: 245, g: 255, b: 250, a: 1},
+ mistyrose: {r: 255, g: 228, b: 225, a: 1},
+ moccasin: {r: 255, g: 228, b: 181, a: 1},
+ navajowhite: {r: 255, g: 222, b: 173, a: 1},
+ navy: {r: 0, g: 0, b: 128, a: 1},
+ oldlace: {r: 253, g: 245, b: 230, a: 1},
+ olive: {r: 128, g: 128, b: 0, a: 1},
+ olivedrab: {r: 107, g: 142, b: 35, a: 1},
+ orange: {r: 255, g: 165, b: 0, a: 1},
+ orangered: {r: 255, g: 69, b: 0, a: 1},
+ orchid: {r: 218, g: 112, b: 214, a: 1},
+ palegoldenrod: {r: 238, g: 232, b: 170, a: 1},
+ palegreen: {r: 152, g: 251, b: 152, a: 1},
+ paleturquoise: {r: 175, g: 238, b: 238, a: 1},
+ palevioletred: {r: 219, g: 112, b: 147, a: 1},
+ papayawhip: {r: 255, g: 239, b: 213, a: 1},
+ peachpuff: {r: 255, g: 218, b: 185, a: 1},
+ peru: {r: 205, g: 133, b: 63, a: 1},
+ pink: {r: 255, g: 192, b: 203, a: 1},
+ plum: {r: 221, g: 160, b: 221, a: 1},
+ powderblue: {r: 176, g: 224, b: 230, a: 1},
+ purple: {r: 128, g: 0, b: 128, a: 1},
+ red: {r: 255, g: 0, b: 0, a: 1},
+ rosybrown: {r: 188, g: 143, b: 143, a: 1},
+ royalblue: {r: 65, g: 105, b: 225, a: 1},
+ saddlebrown: {r: 139, g: 69, b: 19, a: 1},
+ salmon: {r: 250, g: 128, b: 114, a: 1},
+ sandybrown: {r: 244, g: 164, b: 96, a: 1},
+ seagreen: {r: 46, g: 139, b: 87, a: 1},
+ seashell: {r: 255, g: 245, b: 238, a: 1},
+ sienna: {r: 160, g: 82, b: 45, a: 1},
+ silver: {r: 192, g: 192, b: 192, a: 1},
+ skyblue: {r: 135, g: 206, b: 235, a: 1},
+ slateblue: {r: 106, g: 90, b: 205, a: 1},
+ slategray: {r: 112, g: 128, b: 144, a: 1},
+ slategrey: {r: 112, g: 128, b: 144, a: 1},
+ snow: {r: 255, g: 250, b: 250, a: 1},
+ springgreen: {r: 0, g: 255, b: 127, a: 1},
+ steelblue: {r: 70, g: 130, b: 180, a: 1},
+ tan: {r: 210, g: 180, b: 140, a: 1},
+ teal: {r: 0, g: 128, b: 128, a: 1},
+ thistle: {r: 216, g: 191, b: 216, a: 1},
+ tomato: {r: 255, g: 99, b: 71, a: 1},
+ turquoise: {r: 64, g: 224, b: 208, a: 1},
+ violet: {r: 238, g: 130, b: 238, a: 1},
+ wheat: {r: 245, g: 222, b: 179, a: 1},
+ white: {r: 255, g: 255, b: 255, a: 1},
+ whitesmoke: {r: 245, g: 245, b: 245, a: 1},
+ yellow: {r: 255, g: 255, b: 0, a: 1},
+ yellowgreen: {r: 154, g: 205, b: 50, a: 1}
+};
+
+const convertHue = (p, q, h) => {
+ if (h < 0) h++;
+ if (h > 1) h--;
+
+ let color;
+
+ if (h * 6 < 1) {
+ color = p + ((q - p) * h * 6);
+ } else if (h * 2 < 1) {
+ color = q;
+ } else if (h * 3 < 2) {
+ color = p + ((q - p) * ((2 / 3) - h) * 6);
+ } else {
+ color = p;
+ }
+
+ return Math.round(color * 255);
+};
+
+const convertRGB = value => {
+ const str = value.toString(16);
+ if (value < 16) return `0${str}`;
+
+ return str;
+};
+
+const mixValue = (a, b, ratio) => a + ((b - a) * ratio);
+
+class Color {
+
+ /**
+ * @param {string|{ r: number; g: number; b: number; a: number;}} color
+ */
+ constructor(color) {
+ if (typeof color === 'string') {
+ this._parse(color);
+ } else if (color != null && typeof color === 'object') {
+ this.r = color.r | 0;
+ this.g = color.g | 0;
+ this.b = color.b | 0;
+ this.a = +color.a;
+ } else {
+ throw new TypeError('color is required!');
+ }
+
+ if (this.r < 0 || this.r > 255
+ || this.g < 0 || this.g > 255
+ || this.b < 0 || this.b > 255
+ || this.a < 0 || this.a > 1) {
+ throw new RangeError(`{r: ${this.r}, g: ${this.g}, b: ${this.b}, a: ${this.a}} is invalid.`);
+ }
+ }
+
+ /**
+ * @param {string} color
+ */
+ _parse(color) {
+ color = color.toLowerCase();
+
+ if (Object.prototype.hasOwnProperty.call(colorNames, color)) {
+ const obj = colorNames[color];
+
+ this.r = obj.r;
+ this.g = obj.g;
+ this.b = obj.b;
+ this.a = obj.a;
+
+ return;
+ }
+
+ if (rHex3.test(color)) {
+ const txt = color.substring(1);
+ const code = parseInt(txt, 16);
+
+ this.r = ((code & 0xF00) >> 8) * 17;
+ this.g = ((code & 0xF0) >> 4) * 17;
+ this.b = (code & 0xF) * 17;
+ this.a = 1;
+
+ return;
+ }
+
+ if (rHex6.test(color)) {
+ const txt = color.substring(1);
+ const code = parseInt(txt, 16);
+
+ this.r = (code & 0xFF0000) >> 16;
+ this.g = (code & 0xFF00) >> 8;
+ this.b = code & 0xFF;
+ this.a = 1;
+
+ return;
+ }
+
+ let match = color.match(rRGB);
+
+ if (match) {
+ this.r = match[1] | 0;
+ this.g = match[2] | 0;
+ this.b = match[3] | 0;
+ this.a = match[4] ? +match[4] : 1;
+
+ return;
+ }
+
+ match = color.match(rHSL);
+
+ if (match) {
+ const h = +match[1] / 360;
+ const s = +match[2] / 100;
+ const l = +match[3] / 100;
+
+ this.a = match[4] ? +match[4] : 1;
+
+ if (!s) {
+ this.r = this.g = this.b = l * 255;
+ }
+
+ const q = l < 0.5 ? l * (1 + s) : l + s - (l * s);
+ const p = (2 * l) - q;
+
+ const rt = h + (1 / 3);
+ const gt = h;
+ const bt = h - (1 / 3);
+
+ this.r = convertHue(p, q, rt);
+ this.g = convertHue(p, q, gt);
+ this.b = convertHue(p, q, bt);
+
+ return;
+ }
+
+ throw new Error(`${color} is not a supported color format.`);
+ }
+
+ toString() {
+ if (this.a === 1) {
+ const r = convertRGB(this.r);
+ const g = convertRGB(this.g);
+ const b = convertRGB(this.b);
+
+ if (this.r % 17 || this.g % 17 || this.b % 17) {
+ return `#${r}${g}${b}`;
+ }
+
+ return `#${r[0]}${g[0]}${b[0]}`;
+ }
+
+ return `rgba(${this.r}, ${this.g}, ${this.b}, ${parseFloat(this.a.toFixed(2))})`;
+ }
+
+ /**
+ * @param {string|{ r: number; g: number; b: number; a: number;}} color
+ * @param {number} ratio
+ */
+ mix(color, ratio) {
+ if (ratio > 1 || ratio < 0) {
+ throw new RangeError('Valid numbers is only between 0 and 1.');
+ }
+ switch (ratio) {
+ case 0:
+ return new Color(this);
+
+ case 1:
+ return new Color(color);
+ }
+
+ return new Color({
+ r: Math.round(mixValue(this.r, color.r, ratio)),
+ g: Math.round(mixValue(this.g, color.g, ratio)),
+ b: Math.round(mixValue(this.b, color.b, ratio)),
+ a: mixValue(this.a, color.a, ratio)
+ });
+ }
+}
+
+module.exports = Color;
diff --git a/lib/escape_diacritic.js b/lib/escape_diacritic.js
index 2b39d827..5e94465d 100644
--- a/lib/escape_diacritic.js
+++ b/lib/escape_diacritic.js
@@ -1,6 +1,6 @@
'use strict';
-var defaultDiacriticsRemovalap = [
+const defaultDiacriticsRemovalap = [
{'base': 'A', 'letters': '\u0041\u24B6\uFF21\u00C0\u00C1\u00C2\u1EA6\u1EA4\u1EAA\u1EA8\u00C3\u0100\u0102\u1EB0\u1EAE\u1EB4\u1EB2\u0226\u01E0\u00C4\u01DE\u1EA2\u00C5\u01FA\u01CD\u0200\u0202\u1EA0\u1EAC\u1EB6\u1E00\u0104\u023A\u2C6F'},
{'base': 'AA', 'letters': '\uA732'},
{'base': 'AE', 'letters': '\u00C6\u01FC\u01E2'},
@@ -89,12 +89,12 @@ var defaultDiacriticsRemovalap = [
{'base': 'z', 'letters': '\u007A\u24E9\uFF5A\u017A\u1E91\u017C\u017E\u1E93\u1E95\u01B6\u0225\u0240\u2C6C\uA763'}
];
-var diacriticsMap = {};
+const diacriticsMap = {};
-for (var i = 0; i < defaultDiacriticsRemovalap.length; i++) {
- var letters = defaultDiacriticsRemovalap[i].letters.split('');
+for (let i = 0; i < defaultDiacriticsRemovalap.length; i++) {
+ const letters = defaultDiacriticsRemovalap[i].letters.split('');
- for (var j = 0; j < letters.length; j++) {
+ for (let j = 0; j < letters.length; j++) {
diacriticsMap[letters[j]] = defaultDiacriticsRemovalap[i].base;
}
}
@@ -104,9 +104,7 @@ function escapeDiacritic(str) {
// http://stackoverflow.com/a/18391901
// eslint-disable-next-line no-control-regex
- return str.replace(/[^\u0000-\u007E]/g, function(a) {
- return diacriticsMap[a] || a;
- });
+ return str.replace(/[^\u0000-\u007E]/g, a => diacriticsMap[a] || a);
}
module.exports = escapeDiacritic;
diff --git a/lib/escape_html.js b/lib/escape_html.js
index f094eb66..8c51211b 100644
--- a/lib/escape_html.js
+++ b/lib/escape_html.js
@@ -1,6 +1,6 @@
'use strict';
-var htmlEntityMap = {
+const htmlEntityMap = {
'&': '&',
'<': '<',
'>': '>',
@@ -13,9 +13,7 @@ function escapeHTML(str) {
if (typeof str !== 'string') throw new TypeError('str must be a string!');
// http://stackoverflow.com/a/12034334
- return str.replace(/[&<>"'/]/g, function(a) {
- return htmlEntityMap[a];
- });
+ return str.replace(/[&<>"'/]/g, a => htmlEntityMap[a]);
}
module.exports = escapeHTML;
diff --git a/lib/hash.js b/lib/hash.js
index e48f0ee2..57a1547e 100644
--- a/lib/hash.js
+++ b/lib/hash.js
@@ -1,25 +1,27 @@
'use strict';
-var Stream = require('stream');
-var Transform = Stream.Transform;
-var crypto = require('crypto');
+const { Transform } = require('stream');
+const crypto = require('crypto');
-var ALGORITHM = 'sha1';
+const ALGORITHM = 'sha1';
-function HashStream() {
- Transform.call(this, {
- objectMode: true
- });
+function createSha1Hash() {
+ return crypto.createHash(ALGORITHM);
+}
- this._hash = crypto.createHash(ALGORITHM);
+/**
+ * @deprecated
+ * createHash() is stream class.
+ */
+function HashStream() {
+ Transform.call(this);
+ this._hash = createSha1Hash();
}
require('util').inherits(HashStream, Transform);
HashStream.prototype._transform = function(chunk, enc, callback) {
- var buffer = chunk instanceof Buffer ? chunk : Buffer.from(chunk, enc);
-
- this._hash.update(buffer);
+ this._hash.update(chunk);
callback();
};
@@ -28,10 +30,11 @@ HashStream.prototype._flush = function(callback) {
callback();
};
-exports.hash = function(content) {
- var hash = crypto.createHash(ALGORITHM);
+exports.hash = content => {
+ const hash = createSha1Hash();
hash.update(content);
return hash.digest();
};
exports.HashStream = HashStream;
+exports.createSha1Hash = createSha1Hash;
diff --git a/lib/highlight.js b/lib/highlight.js
index 6e7d5fd7..0ed2da4d 100644
--- a/lib/highlight.js
+++ b/lib/highlight.js
@@ -1,72 +1,71 @@
'use strict';
-var hljs = require('highlight.js');
-var Entities = require('html-entities').XmlEntities;
-var entities = new Entities();
-var alias = require('../highlight_alias.json');
+const hljs = require('highlight.js');
+const Entities = require('html-entities').XmlEntities;
+const entities = new Entities();
+const alias = require('../highlight_alias.json');
-function highlightUtil(str, options) {
+function highlightUtil(str, options = {}) {
if (typeof str !== 'string') throw new TypeError('str must be a string!');
- options = options || {};
- var useHljs = options.hasOwnProperty('hljs') ? options.hljs : false;
- var gutter = options.hasOwnProperty('gutter') ? options.gutter : true;
- var wrap = options.hasOwnProperty('wrap') ? options.wrap : true;
- var firstLine = options.hasOwnProperty('firstLine') ? +options.firstLine : 1;
- var caption = options.caption;
- var mark = options.hasOwnProperty('mark') ? options.mark : [];
- var tab = options.tab;
+ const useHljs = Object.prototype.hasOwnProperty.call(options, 'hljs') ? options.hljs : false;
+ const {
+ gutter = true,
+ firstLine = 1,
+ caption,
+ mark = [],
+ tab
+ } = options;
+ let { wrap = true } = options;
hljs.configure({ classPrefix: useHljs ? 'hljs-' : ''});
- var data = highlight(str, options);
+ const data = highlight(str, options);
if (useHljs && !gutter) wrap = false;
- var before = useHljs ? '
' : '';
- var after = useHljs ? '
' : '';
+ const before = useHljs ? `` : '';
+ const after = useHljs ? '
' : '';
if (!wrap) return useHljs ? before + data.value + after : data.value;
- var lines = data.value.split('\n');
- var numbers = '';
- var content = '';
- var result = '';
- var line;
+ const lines = data.value.split('\n');
+ let numbers = '';
+ let content = '';
- for (var i = 0, len = lines.length; i < len; i++) {
- line = lines[i];
+ for (let i = 0, len = lines.length; i < len; i++) {
+ let line = lines[i];
if (tab) line = replaceTabs(line, tab);
- numbers += '' + (firstLine + i) + '
';
- content += formatLine(line, firstLine + i, mark, options);
+ numbers += `${Number(firstLine) + i}
`;
+ content += formatLine(line, Number(firstLine) + i, mark, options);
}
- result += '';
+ let result = ``;
if (caption) {
- result += '' + caption + '';
+ result += `${caption}`;
}
result += '';
if (gutter) {
- result += '' + numbers + ' | ';
+ result += `${numbers} | `;
}
- result += '' + before + content + after + ' | ';
+ result += `${before}${content}${after} | `;
result += '
';
return result;
}
function formatLine(line, lineno, marked, options) {
- var useHljs = options.hljs || false;
- var res = useHljs ? '' : '' + line + '' : ' marked">' + line + '';
+ res += useHljs ? `${line}` : ` marked">${line}`;
} else {
- res += useHljs ? line : '">' + line + '';
+ res += useHljs ? line : `">${line}`;
}
res += '
';
@@ -78,10 +77,10 @@ function encodePlainString(str) {
}
function replaceTabs(str, tab) {
- return str.replace(/^\t+/, function(match) {
- var result = '';
+ return str.replace(/^\t+/, match => {
+ let result = '';
- for (var i = 0, len = match.length; i < len; i++) {
+ for (let i = 0, len = match.length; i < len; i++) {
result += tab;
}
@@ -90,22 +89,19 @@ function replaceTabs(str, tab) {
}
function highlight(str, options) {
- var lang = options.lang;
- var autoDetect = options.hasOwnProperty('autoDetect') ? options.autoDetect : false;
+ let { lang } = options;
+ const { autoDetect = false } = options;
if (!lang && autoDetect) {
- lang = (function() {
- var result = hljs.highlightAuto(str);
- if (result.relevance > 0 && result.language) return result.language;
-
- }());
+ const result = hljs.highlightAuto(str);
+ if (result.relevance > 0 && result.language) lang = result.language;
}
if (!lang) {
lang = 'plain';
}
- var result = {
+ const result = {
value: encodePlainString(str),
language: lang.toLowerCase()
};
@@ -126,11 +122,11 @@ function highlight(str, options) {
function tryHighlight(str, lang) {
try {
- var matching = str.match(/(\r?\n)/);
- var separator = matching ? matching[1] : '';
- var lines = matching ? str.split(separator) : [str];
- var result = hljs.highlight(lang, lines.shift());
- var html = result.value;
+ const matching = str.match(/(\r?\n)/);
+ const separator = matching ? matching[1] : '';
+ const lines = matching ? str.split(separator) : [str];
+ let result = hljs.highlight(lang, lines.shift());
+ let html = result.value;
while (lines.length > 0) {
result = hljs.highlight(lang, lines.shift(), false, result.top);
html += separator + result.value;
diff --git a/lib/html_tag.js b/lib/html_tag.js
index 173f9077..8c7541f2 100644
--- a/lib/html_tag.js
+++ b/lib/html_tag.js
@@ -3,13 +3,13 @@
function htmlTag(tag, attrs, text) {
if (!tag) throw new TypeError('tag is required!');
- var result = '<' + tag;
+ let result = `<${tag}`;
- for (var i in attrs) {
- if (attrs[i]) result += ' ' + i + '="' + attrs[i] + '"';
+ for (const i in attrs) {
+ if (attrs[i] != null) result += ` ${i}="${attrs[i]}"`;
}
- result += text == null ? '>' : '>' + text + '' + tag + '>';
+ result += text == null ? '>' : `>${text}${tag}>`;
return result;
}
diff --git a/lib/index.js b/lib/index.js
index eb8fd2ea..f38eac88 100644
--- a/lib/index.js
+++ b/lib/index.js
@@ -1,6 +1,6 @@
'use strict';
-var hash = require('./hash');
+const hash = require('./hash');
exports.escapeDiacritic = require('./escape_diacritic');
exports.escapeHTML = require('./escape_html');
@@ -16,5 +16,6 @@ exports.truncate = require('./truncate');
exports.wordWrap = require('./word_wrap');
exports.hash = hash.hash;
exports.HashStream = hash.HashStream;
+exports.createSha1Hash = hash.createSha1Hash;
exports.CacheStream = require('./cache_stream');
exports.camelCaseKeys = require('./camel_case_keys');
diff --git a/lib/pattern.js b/lib/pattern.js
index f9d07756..c2eecf8c 100644
--- a/lib/pattern.js
+++ b/lib/pattern.js
@@ -1,8 +1,8 @@
'use strict';
-var escapeRegExp = require('./escape_regexp');
+const escapeRegExp = require('./escape_regexp');
-var rParam = /([:*])([\w?]*)?/g;
+const rParam = /([:*])([\w?]*)?/g;
function Pattern(rule) {
if (rule instanceof Pattern) {
@@ -23,18 +23,16 @@ Pattern.prototype.test = function(str) {
};
function regexFilter(rule) {
- return function(str) {
- return str.match(rule);
- };
+ return str => str.match(rule);
}
function stringFilter(rule) {
- var params = [];
+ const params = [];
- var regex = escapeRegExp(rule)
+ const regex = escapeRegExp(rule)
.replace(/\\([*?])/g, '$1')
- .replace(rParam, function(match, operator, name) {
- var str = '';
+ .replace(rParam, (match, operator, name) => {
+ let str = '';
if (operator === '*') {
str = '(.*)?';
@@ -54,15 +52,14 @@ function stringFilter(rule) {
return str;
});
- return function(str) {
- var match = str.match(regex);
+ return str => {
+ const match = str.match(regex);
if (!match) return;
- var result = {};
- var name;
+ const result = {};
- for (var i = 0, len = match.length; i < len; i++) {
- name = params[i - 1];
+ for (let i = 0, len = match.length; i < len; i++) {
+ const name = params[i - 1];
result[i] = match[i];
if (name) result[name] = match[i];
}
diff --git a/lib/permalink.js b/lib/permalink.js
index 96684579..4e31353e 100644
--- a/lib/permalink.js
+++ b/lib/permalink.js
@@ -1,22 +1,22 @@
'use strict';
-var escapeRegExp = require('./escape_regexp');
+const escapeRegExp = require('./escape_regexp');
-var rParam = /:(\w+)/g;
+const rParam = /:(\w+)/g;
function Permalink(rule, options) {
if (!rule) throw new TypeError('rule is required!');
options = options || {};
- var segments = options.segments || {};
- var params = [];
+ const segments = options.segments || {};
+ const params = [];
- var regex = escapeRegExp(rule)
- .replace(rParam, function(match, name) {
+ const regex = escapeRegExp(rule)
+ .replace(rParam, (match, name) => {
params.push(name);
- if (segments.hasOwnProperty(name)) {
- var segment = segments[name];
+ if (Object.prototype.hasOwnProperty.call(segments, name)) {
+ const segment = segments[name];
if (segment instanceof RegExp) {
return segment.source;
@@ -29,7 +29,7 @@ function Permalink(rule, options) {
});
this.rule = rule;
- this.regex = new RegExp('^' + regex + '$');
+ this.regex = new RegExp(`^${regex}$`);
this.params = params;
}
@@ -38,13 +38,13 @@ Permalink.prototype.test = function(str) {
};
Permalink.prototype.parse = function(str) {
- var match = str.match(this.regex);
- var params = this.params;
- var result = {};
+ const match = str.match(this.regex);
+ const { params } = this;
+ const result = {};
if (!match) return;
- for (var i = 1, len = match.length; i < len; i++) {
+ for (let i = 1, len = match.length; i < len; i++) {
result[params[i - 1]] = match[i];
}
@@ -52,9 +52,7 @@ Permalink.prototype.parse = function(str) {
};
Permalink.prototype.stringify = function(data) {
- return this.rule.replace(rParam, function(match, name) {
- return data[name];
- });
+ return this.rule.replace(rParam, (match, name) => data[name]);
};
module.exports = Permalink;
diff --git a/lib/slugize.js b/lib/slugize.js
index 73755c46..0a749a7c 100644
--- a/lib/slugize.js
+++ b/lib/slugize.js
@@ -1,27 +1,26 @@
'use strict';
-var escapeDiacritic = require('./escape_diacritic');
-var escapeRegExp = require('./escape_regexp');
+const escapeDiacritic = require('./escape_diacritic');
+const escapeRegExp = require('./escape_regexp');
// eslint-disable-next-line no-control-regex
-var rControl = /[\u0000-\u001f]/g;
-var rSpecial = /[\s~`!@#$%^&*()\-_+=[\]{}|\\;:"'<>,.?/]+/g;
+const rControl = /[\u0000-\u001f]/g;
+const rSpecial = /[\s~`!@#$%^&*()\-_+=[\]{}|\\;:"'<>,.?/]+/g;
-function slugize(str, options) {
+function slugize(str, options = {}) {
if (typeof str !== 'string') throw new TypeError('str must be a string!');
- options = options || {};
- var separator = options.separator || '-';
- var escapedSep = escapeRegExp(separator);
+ const separator = options.separator || '-';
+ const escapedSep = escapeRegExp(separator);
- var result = escapeDiacritic(str)
+ const result = escapeDiacritic(str)
// Remove control characters
.replace(rControl, '')
// Replace special characters
.replace(rSpecial, separator)
// Remove continous separators
- .replace(new RegExp(escapedSep + '{2,}', 'g'), separator)
+ .replace(new RegExp(`${escapedSep}{2,}`, 'g'), separator)
// Remove prefixing and trailing separtors
- .replace(new RegExp('^' + escapedSep + '+|' + escapedSep + '+$', 'g'), '');
+ .replace(new RegExp(`^${escapedSep}+|${escapedSep}+$`, 'g'), '');
switch (options.transform) {
case 1:
diff --git a/lib/spawn.js b/lib/spawn.js
index d8ebd0ad..13d2c4af 100644
--- a/lib/spawn.js
+++ b/lib/spawn.js
@@ -1,40 +1,39 @@
'use strict';
-var spawn = require('cross-spawn');
-var Promise = require('bluebird');
-var CacheStream = require('./cache_stream');
+const spawn = require('cross-spawn');
+const Promise = require('bluebird');
+const CacheStream = require('./cache_stream');
-function promiseSpawn(command, args, options) {
+function promiseSpawn(command, args = [], options) {
if (!command) throw new TypeError('command is required!');
- if (!options && args && !Array.isArray(args)) {
+ if (!options && !Array.isArray(args)) {
options = args;
args = [];
}
- args = args || [];
options = options || {};
- return new Promise(function(resolve, reject) {
- var task = spawn(command, args, options);
- var verbose = options.verbose;
- var encoding = options.hasOwnProperty('encoding') ? options.encoding : 'utf8';
- var stdoutCache = new CacheStream();
- var stderrCache = new CacheStream();
+ return new Promise((resolve, reject) => {
+ const task = spawn(command, args, options);
+ const verbose = options.verbose;
+ const { encoding = 'utf8' } = options;
+ const stdoutCache = new CacheStream();
+ const stderrCache = new CacheStream();
if (task.stdout) {
- var stdout = task.stdout.pipe(stdoutCache);
+ const stdout = task.stdout.pipe(stdoutCache);
if (verbose) stdout.pipe(process.stdout);
}
if (task.stderr) {
- var stderr = task.stderr.pipe(stderrCache);
+ const stderr = task.stderr.pipe(stderrCache);
if (verbose) stderr.pipe(process.stderr);
}
- task.on('close', function(code) {
+ task.on('close', code => {
if (code) {
- var e = new Error(getCache(stderrCache, encoding));
+ const e = new Error(getCache(stderrCache, encoding));
e.code = code;
return reject(e);
@@ -47,9 +46,9 @@ function promiseSpawn(command, args, options) {
// Listen to exit events if neither stdout and stderr exist (inherit stdio)
if (!task.stdout && !task.stderr) {
- task.on('exit', function(code) {
+ task.on('exit', code => {
if (code) {
- var e = new Error('Spawn failed');
+ const e = new Error('Spawn failed');
e.code = code;
return reject(e);
@@ -62,7 +61,7 @@ function promiseSpawn(command, args, options) {
}
function getCache(stream, encoding) {
- var buf = stream.getCache();
+ const buf = stream.getCache();
stream.destroy();
if (!encoding) return buf;
diff --git a/lib/truncate.js b/lib/truncate.js
index 50775712..0dbd1dac 100644
--- a/lib/truncate.js
+++ b/lib/truncate.js
@@ -1,24 +1,22 @@
'use strict';
-function truncate(str, options) {
+function truncate(str, options = {}) {
if (typeof str !== 'string') throw new TypeError('str must be a string!');
- options = options || {};
- var length = options.length || 30;
- var omission = options.omission || '...';
- var separator = options.separator;
- var omissionLength = omission.length;
+ const length = options.length || 30;
+ const omission = options.omission || '...';
+ const { separator } = options;
+ const omissionLength = omission.length;
if (str.length < length) return str;
if (separator) {
- var words = str.split(separator);
- var word = '';
- var result = '';
- var resultLength = 0;
+ const words = str.split(separator);
+ let result = '';
+ let resultLength = 0;
- for (var i = 0, len = words.length; i < len; i++) {
- word = words[i];
+ for (let i = 0, len = words.length; i < len; i++) {
+ const word = words[i];
if (resultLength + word.length + omissionLength < length) {
result += word + separator;
diff --git a/lib/word_wrap.js b/lib/word_wrap.js
index 9a552727..23fb6df6 100644
--- a/lib/word_wrap.js
+++ b/lib/word_wrap.js
@@ -1,17 +1,15 @@
'use strict';
// https://github.com/rails/rails/blob/v4.2.0/actionview/lib/action_view/helpers/text_helper.rb#L240
-function wordWrap(str, options) {
+function wordWrap(str, options = {}) {
if (typeof str !== 'string') throw new TypeError('str must be a string!');
- options = options || {};
- var width = options.width || 80;
- var regex = new RegExp('(.{1,' + width + '})(\\s+|$)', 'g');
- var lines = str.split('\n');
- var line = '';
+ const width = options.width || 80;
+ const regex = new RegExp(`(.{1,${width}})(\\s+|$)`, 'g');
+ const lines = str.split('\n');
- for (var i = 0, len = lines.length; i < len; i++) {
- line = lines[i];
+ for (let i = 0, len = lines.length; i < len; i++) {
+ const line = lines[i];
if (line.length > width) {
lines[i] = line.replace(regex, '$1\n').trim();
@@ -22,4 +20,3 @@ function wordWrap(str, options) {
}
module.exports = wordWrap;
-
diff --git a/package.json b/package.json
index 76dd8f8d..ed599639 100644
--- a/package.json
+++ b/package.json
@@ -1,18 +1,24 @@
{
"name": "hexo-util",
- "version": "0.6.3",
+ "version": "1.0.0",
"description": "Utilities for Hexo.",
"main": "lib/index",
"scripts": {
"eslint": "eslint .",
"test": "mocha test/index.js",
- "test-cov": "istanbul cover --print both _mocha -- test/index.js",
- "build:highlight": "node scripts/build_highlight_alias.js > highlight_alias.json",
+ "test-cov": "nyc npm run test",
+ "build:highlight": "node scripts/build_highlight_alias.js",
"prepare": "npm run build:highlight"
},
"directories": {
- "lib": "./lib"
+ "lib": "./lib",
+ "scripts": "./scripts"
},
+ "files": [
+ "lib/",
+ "scripts/",
+ "highlight_alias.json"
+ ],
"repository": "hexojs/hexo-util",
"homepage": "https://hexo.io/",
"keywords": [
@@ -26,21 +32,24 @@
],
"license": "MIT",
"devDependencies": {
- "chai": "^3.5.0",
- "eslint": "^4.19.1",
+ "chai": "^4.2.0",
+ "chai-as-promised": "^7.1.1",
+ "eslint": "^6.0.1",
"eslint-config-hexo": "^3.0.0",
"html-tag-validator": "^1.5.0",
- "istanbul": "^0.4.3",
- "jscs-preset-hexo": "^1.0.1",
- "mocha": "^5.1.0",
- "rewire": "^2.5.1"
+ "mocha": "^6.0.1",
+ "nyc": "^14.1.1",
+ "rewire": "^4.0.1"
},
"dependencies": {
- "bluebird": "^3.4.0",
+ "bluebird": "^3.5.2",
"camel-case": "^3.0.0",
- "cross-spawn": "^4.0.0",
- "highlight.js": "^9.4.0",
- "html-entities": "^1.2.0",
- "striptags": "^2.1.1"
+ "cross-spawn": "^6.0.5",
+ "highlight.js": "^9.13.1",
+ "html-entities": "^1.2.1",
+ "striptags": "^3.1.1"
+ },
+ "engines": {
+ "node": ">=8.6.0"
}
}
diff --git a/scripts/build_highlight_alias.js b/scripts/build_highlight_alias.js
index 6f1b6184..c2e97419 100644
--- a/scripts/build_highlight_alias.js
+++ b/scripts/build_highlight_alias.js
@@ -1,24 +1,29 @@
'use strict';
-var hljs = require('highlight.js');
-var languages = hljs.listLanguages();
+const hljs = require('highlight.js');
+const languages = hljs.listLanguages();
+const fs = require('fs');
-var result = {
+const result = {
languages: languages,
aliases: {}
};
-languages.forEach(function(lang) {
+languages.forEach(lang => {
result.aliases[lang] = lang;
- var def = require('highlight.js/lib/languages/' + lang)(hljs);
- var aliases = def.aliases;
+ const def = require('highlight.js/lib/languages/' + lang)(hljs);
+ const aliases = def.aliases;
if (aliases) {
- aliases.forEach(function(alias) {
+ aliases.forEach(alias => {
result.aliases[alias] = lang;
});
}
});
-console.log(JSON.stringify(result));
+const stream = fs.createWriteStream('highlight_alias.json');
+stream.write(JSON.stringify(result));
+stream.on('end', () => {
+ stream.end();
+});
diff --git a/test/index.js b/test/index.js
index 855b61c8..117491df 100644
--- a/test/index.js
+++ b/test/index.js
@@ -1,8 +1,9 @@
'use strict';
-describe('util', function() {
+describe('util', () => {
require('./scripts/cache_stream');
require('./scripts/camel_case_keys');
+ require('./scripts/color');
require('./scripts/escape_diacritic');
require('./scripts/escape_html');
require('./scripts/escape_regexp');
diff --git a/test/scripts/cache_stream.js b/test/scripts/cache_stream.js
index 37e7bc9a..3e80262e 100644
--- a/test/scripts/cache_stream.js
+++ b/test/scripts/cache_stream.js
@@ -1,26 +1,28 @@
'use strict';
-var Readable = require('stream').Readable;
+require('chai').should();
-describe('CacheStream', function() {
- var CacheStream = require('../../lib/cache_stream');
+const { Readable } = require('stream');
- it('default', function() {
- var src = new Readable();
- var cacheStream = new CacheStream();
- var content = Buffer.from('test');
+describe('CacheStream', () => {
+ const CacheStream = require('../../lib/cache_stream');
+
+ it('default', () => {
+ const src = new Readable();
+ const cacheStream = new CacheStream();
+ const content = Buffer.from('test');
src.push(content);
src.push(null);
src.pipe(cacheStream);
- cacheStream.on('finish', function() {
+ cacheStream.on('finish', () => {
cacheStream.getCache().should.eql(content);
});
});
- it('destroy', function() {
- var cacheStream = new CacheStream();
+ it('destroy', () => {
+ const cacheStream = new CacheStream();
cacheStream._cache = [Buffer.alloc(1)];
cacheStream.destroy();
diff --git a/test/scripts/camel_case_keys.js b/test/scripts/camel_case_keys.js
index 94dc2aaf..d936e525 100644
--- a/test/scripts/camel_case_keys.js
+++ b/test/scripts/camel_case_keys.js
@@ -1,12 +1,12 @@
'use strict';
-var should = require('chai').should(); // eslint-disable-line
+require('chai').should();
-describe('camelCaseKeys', function() {
- var camelCaseKeys = require('../../lib/camel_case_keys');
+describe('camelCaseKeys', () => {
+ const camelCaseKeys = require('../../lib/camel_case_keys');
- it('default', function() {
- var result = camelCaseKeys({
+ it('default', () => {
+ const result = camelCaseKeys({
foo_bar: 'test'
});
@@ -16,16 +16,12 @@ describe('camelCaseKeys', function() {
});
});
- it('obj must be an object', function() {
- try {
- camelCaseKeys();
- } catch (err) {
- err.should.have.property('message', 'obj must be an object!');
- }
+ it('obj must be an object', () => {
+ camelCaseKeys.should.throw('obj must be an object!');
});
- it('setter', function() {
- var result = camelCaseKeys({
+ it('setter', () => {
+ const result = camelCaseKeys({
foo_bar: 'test'
});
@@ -33,8 +29,8 @@ describe('camelCaseKeys', function() {
result.fooBar.should.eql('new');
});
- it('ignore prefixing underscore', function() {
- var result = camelCaseKeys({
+ it('ignore prefixing underscore', () => {
+ const result = camelCaseKeys({
_foo_bar: 'test',
__bar_baz: 'foo'
});
@@ -47,13 +43,8 @@ describe('camelCaseKeys', function() {
});
});
- it('do nothing if the key is camelCase', function() {
- var result = camelCaseKeys({
- fooBar: 'test'
- });
-
- result.should.eql({
- fooBar: 'test'
- });
+ it('do nothing if the key is camelCase', () => {
+ const result = camelCaseKeys({ fooBar: 'test' });
+ result.should.eql({ fooBar: 'test' });
});
});
diff --git a/test/scripts/color.js b/test/scripts/color.js
new file mode 100644
index 00000000..3f943fb3
--- /dev/null
+++ b/test/scripts/color.js
@@ -0,0 +1,55 @@
+'use strict';
+
+require('chai').should();
+
+describe('color', () => {
+ const Color = require('../../lib/color');
+
+ it('name', () => {
+ const red = new Color('red');
+ const pink = new Color('pink');
+ const mid1 = red.mix(pink, 1 / 3);
+ const mid2 = red.mix(pink, 2 / 3);
+
+ `${red}`.should.eql('#f00');
+ `${pink}`.should.eql('#ffc0cb');
+ `${mid1}`.should.eql('#ff4044');
+ `${mid2}`.should.eql('#ff8087');
+ });
+
+ it('hex', () => {
+ const red = new Color('#f00');
+ const pink = new Color('#ffc0cb');
+ const mid1 = red.mix(pink, 1 / 3);
+ const mid2 = red.mix(pink, 2 / 3);
+
+ `${red}`.should.eql('#f00');
+ `${pink}`.should.eql('#ffc0cb');
+ `${mid1}`.should.eql('#ff4044');
+ `${mid2}`.should.eql('#ff8087');
+ });
+
+ it('RGBA', () => {
+ const steelblueA = new Color('rgba(70, 130, 180, 0.3)');
+ const steelblue = new Color('rgb(70, 130, 180)');
+ const mid1 = steelblueA.mix(steelblue, 1 / 3);
+ const mid2 = steelblueA.mix(steelblue, 2 / 3);
+
+ `${steelblueA}`.should.eql('rgba(70, 130, 180, 0.3)');
+ `${steelblue}`.should.eql('#4682b4');
+ `${mid1}`.should.eql('rgba(70, 130, 180, 0.53)');
+ `${mid2}`.should.eql('rgba(70, 130, 180, 0.77)');
+ });
+
+ it('HSLA', () => {
+ const steelblueA = new Color('hsla(207, 44%, 49%, 0.3)');
+ const steelblue = new Color('hsl(207, 44%, 49%)');
+ const mid1 = steelblueA.mix(steelblue, 1 / 3);
+ const mid2 = steelblueA.mix(steelblue, 2 / 3);
+
+ `${steelblueA}`.should.eql('rgba(70, 130, 180, 0.3)');
+ `${steelblue}`.should.eql('#4682b4');
+ `${mid1}`.should.eql('rgba(70, 130, 180, 0.53)');
+ `${mid2}`.should.eql('rgba(70, 130, 180, 0.77)');
+ });
+});
diff --git a/test/scripts/escape_diacritic.js b/test/scripts/escape_diacritic.js
index 225ac4d4..d8579254 100644
--- a/test/scripts/escape_diacritic.js
+++ b/test/scripts/escape_diacritic.js
@@ -1,19 +1,15 @@
'use strict';
-var should = require('chai').should(); // eslint-disable-line
+require('chai').should();
-describe('escapeDiacritic', function() {
- var escapeDiacritic = require('../../lib/escape_diacritic');
+describe('escapeDiacritic', () => {
+ const escapeDiacritic = require('../../lib/escape_diacritic');
- it('default', function() {
+ it('default', () => {
escapeDiacritic('Hell\u00F2 w\u00F2rld').should.eql('Hello world');
});
- it('str must be a string', function() {
- try {
- escapeDiacritic();
- } catch (err) {
- err.should.have.property('message', 'str must be a string!');
- }
+ it('str must be a string', () => {
+ escapeDiacritic.should.throw('str must be a string!');
});
});
diff --git a/test/scripts/escape_html.js b/test/scripts/escape_html.js
index 68fc6ede..25d64841 100644
--- a/test/scripts/escape_html.js
+++ b/test/scripts/escape_html.js
@@ -1,19 +1,15 @@
'use strict';
-var should = require('chai').should(); // eslint-disable-line
+require('chai').should();
-describe('escapeHTML', function() {
- var escapeHTML = require('../../lib/escape_html');
+describe('escapeHTML', () => {
+ const escapeHTML = require('../../lib/escape_html');
- it('default', function() {
+ it('default', () => {
escapeHTML('Hello "world".
').should.eql('<p>Hello "world".</p>');
});
- it('str must be a string', function() {
- try {
- escapeHTML();
- } catch (err) {
- err.should.have.property('message', 'str must be a string!');
- }
+ it('str must be a string', () => {
+ escapeHTML.should.throw('str must be a string!');
});
});
diff --git a/test/scripts/escape_regexp.js b/test/scripts/escape_regexp.js
index f74b6deb..d9ad11b7 100644
--- a/test/scripts/escape_regexp.js
+++ b/test/scripts/escape_regexp.js
@@ -1,19 +1,15 @@
'use strict';
-var should = require('chai').should(); // eslint-disable-line
+require('chai').should();
-describe('escapeRegExp', function() {
- var escapeRegExp = require('../../lib/escape_regexp');
+describe('escapeRegExp', () => {
+ const escapeRegExp = require('../../lib/escape_regexp');
- it('default', function() {
+ it('default', () => {
escapeRegExp('hello*world').should.eql('hello\\*world');
});
- it('str must be a string', function() {
- try {
- escapeRegExp();
- } catch (err) {
- err.should.have.property('message', 'str must be a string!');
- }
+ it('str must be a string', () => {
+ escapeRegExp.should.throw('str must be a string!');
});
});
diff --git a/test/scripts/hash.js b/test/scripts/hash.js
index 360e2f8a..eac02297 100644
--- a/test/scripts/hash.js
+++ b/test/scripts/hash.js
@@ -1,30 +1,49 @@
'use strict';
-var should = require('chai').should(); // eslint-disable-line
-var crypto = require('crypto');
+require('chai').should();
+const crypto = require('crypto');
function sha1(content) {
- var hash = crypto.createHash('sha1');
+ const hash = crypto.createHash('sha1');
hash.update(content);
return hash.digest();
}
-describe('hash', function() {
- var hash = require('../../lib/hash');
+describe('hash', () => {
+ const hash = require('../../lib/hash');
- it('hash', function() {
- var content = '123456';
+ it('hash', () => {
+ const content = '123456';
hash.hash(content).should.eql(sha1(content));
});
- it('HashStream', function() {
- var content = '123456';
- var stream = new hash.HashStream();
+ it('HashStream', () => {
+ const content = '123456';
+ const stream = new hash.HashStream();
stream.write(Buffer.from(content));
stream.end();
stream.read().should.eql(sha1(content));
});
+
+ it('createSha1Hash', () => {
+ const _sha1 = hash.createSha1Hash();
+ const content = '123456';
+ _sha1.update(content);
+ _sha1.digest().should.eql(sha1(content));
+ });
+
+ it('createSha1Hash - streamMode', () => {
+ const content1 = '123456';
+ const content2 = '654321';
+ const stream = hash.createSha1Hash();
+ // explicit convert
+ stream.write(Buffer.from(content1));
+ // implicit convert
+ stream.write(content2);
+ stream.end();
+ stream.read().should.eql(sha1(content1 + content2));
+ });
});
diff --git a/test/scripts/highlight.js b/test/scripts/highlight.js
index 40812a32..5da3b62f 100644
--- a/test/scripts/highlight.js
+++ b/test/scripts/highlight.js
@@ -1,32 +1,32 @@
'use strict';
-var should = require('chai').should(); // eslint-disable-line
-var hljs = require('highlight.js');
-var Entities = require('html-entities').XmlEntities;
-var entities = new Entities();
-var validator = require('html-tag-validator');
+const should = require('chai').should(); // eslint-disable-line
+const hljs = require('highlight.js');
+const Entities = require('html-entities').XmlEntities;
+const entities = new Entities();
+const validator = require('html-tag-validator');
-var testJson = {
+const testJson = {
foo: 1,
bar: 2
};
-var testString = JSON.stringify(testJson, null, ' ');
+const testString = JSON.stringify(testJson, null, ' ');
-var start = '';
+const start = '';
-var gutterStart = '';
-var gutterEnd = ' | ';
+const gutterStart = '';
+const gutterEnd = ' | ';
-var codeStart = '';
-var codeEnd = ' | ';
+const codeStart = '';
+const codeEnd = ' | ';
function gutter(start, end) {
- var result = gutterStart;
+ let result = gutterStart;
- for (var i = start; i <= end; i++) {
- result += '' + i + '
';
+ for (let i = start; i <= end; i++) {
+ result += `${i}
`;
}
result += gutterEnd;
@@ -35,7 +35,7 @@ function gutter(start, end) {
}
function code(str, lang) {
- var data;
+ let data;
if (lang) {
data = hljs.highlight(lang.toLowerCase(), str);
@@ -45,32 +45,19 @@ function code(str, lang) {
data = {value: entities.encode(str)};
}
- var lines = data.value.split('\n');
- var result = codeStart;
+ const lines = data.value.split('\n');
- for (var i = 0, len = lines.length; i < len; i++) {
- result += '' + lines[i] + '
';
- }
-
- result += codeEnd;
-
- return result;
+ return lines.reduce((prev, current) => {
+ return `${prev}${current}
`;
+ }, codeStart) + codeEnd;
}
-function assertResult(result) {
- var expected = start;
-
- for (var i = 1, len = arguments.length; i < len; i++) {
- expected += arguments[i];
- }
-
- expected += end;
-
- result.should.eql(expected);
+function assertResult(result, ...args) {
+ result.should.eql(start + args.join('') + end);
}
function validateHtmlAsync(str, done) {
- validator(str, function(err, ast) {
+ validator(str, (err, ast) => {
if (err) {
done(err);
} else {
@@ -79,43 +66,39 @@ function validateHtmlAsync(str, done) {
});
}
-describe('highlight', function() {
- var highlight = require('../../lib/highlight');
+describe('highlight', () => {
+ const highlight = require('../../lib/highlight');
- it('default', function(done) {
- var result = highlight(testString);
+ it('default', done => {
+ const result = highlight(testString);
assertResult(result, gutter(1, 4), code(testString));
validateHtmlAsync(result, done);
});
- it('str must be a string', function() {
- try {
- highlight();
- } catch (err) {
- err.should.have.property('message', 'str must be a string!');
- }
+ it('str must be a string', () => {
+ highlight.should.throw('str must be a string!');
});
- it('gutter: false', function(done) {
- var result = highlight(testString, {gutter: false});
+ it('gutter: false', done => {
+ const result = highlight(testString, {gutter: false});
assertResult(result, code(testString));
validateHtmlAsync(result, done);
});
- it('wrap: false', function(done) {
- var result = highlight(testString, {wrap: false});
+ it('wrap: false', done => {
+ const result = highlight(testString, {wrap: false});
result.should.eql(entities.encode(testString));
validateHtmlAsync(result, done);
});
- it('firstLine', function(done) {
- var result = highlight(testString, {firstLine: 3});
+ it('firstLine', done => {
+ const result = highlight(testString, {firstLine: 3});
assertResult(result, gutter(3, 6), code(testString));
validateHtmlAsync(result, done);
});
- it('lang = json', function(done) {
- var result = highlight(testString, {lang: 'json'});
+ it('lang = json', done => {
+ const result = highlight(testString, {lang: 'json'});
result.should.eql([
'',
@@ -126,8 +109,8 @@ describe('highlight', function() {
validateHtmlAsync(result, done);
});
- it('auto detect', function(done) {
- var result = highlight(testString, {autoDetect: true});
+ it('auto detect', done => {
+ const result = highlight(testString, {autoDetect: true});
result.should.eql([
'',
@@ -138,16 +121,16 @@ describe('highlight', function() {
validateHtmlAsync(result, done);
});
- it('don\'t highlight if language not found', function(done) {
- var result = highlight('test', {lang: 'jrowiejrowi'});
+ it('don\'t highlight if language not found', done => {
+ const result = highlight('test', {lang: 'jrowiejrowi'});
assertResult(result, gutter(1, 1), code('test'));
validateHtmlAsync(result, done);
});
it('don\'t highlight if parse failed');
- it('caption', function(done) {
- var result = highlight(testString, {
+ it('caption', done => {
+ const result = highlight(testString, {
caption: 'hello world'
});
@@ -160,15 +143,15 @@ describe('highlight', function() {
validateHtmlAsync(result, done);
});
- it('tab', function(done) {
- var str = [
+ it('tab', done => {
+ const str = [
'function fib(i){',
'\tif (i <= 1) return i;',
'\treturn fib(i - 1) + fib(i - 2);',
'}'
].join('\n');
- var result = highlight(str, {tab: ' ', lang: 'js'});
+ const result = highlight(str, {tab: ' ', lang: 'js'});
result.should.eql([
'',
@@ -179,8 +162,8 @@ describe('highlight', function() {
validateHtmlAsync(result, done);
});
- it('escape html entity', function(done) {
- var str = [
+ it('escape html entity', done => {
+ const str = [
'deploy:',
' type: git',
' repo: ',
@@ -188,7 +171,7 @@ describe('highlight', function() {
' message: [message]'
].join('\n');
- var result = highlight(str);
+ const result = highlight(str);
result.should.include('<repository url>');
validateHtmlAsync(result, done);
});
@@ -205,8 +188,8 @@ describe('highlight', function() {
validateHtmlAsync(result, done);
});
- it('parse multi-line strings correctly', function(done) {
- var str = [
+ it('parse multi-line strings correctly', done => {
+ const str = [
'var string = `',
' Multi',
' line',
@@ -214,7 +197,7 @@ describe('highlight', function() {
'`'
].join('\n');
- var result = highlight(str, {lang: 'js'});
+ const result = highlight(str, {lang: 'js'});
result.should.eql([
'',
gutter(1, 5),
@@ -224,8 +207,8 @@ describe('highlight', function() {
validateHtmlAsync(result, done);
});
- it('parse multi-line strings including empty line', function(done) {
- var str = [
+ it('parse multi-line strings including empty line', done => {
+ const str = [
'var string = `',
' Multi',
'',
@@ -233,7 +216,7 @@ describe('highlight', function() {
'`'
].join('\n');
- var result = highlight(str, {lang: 'js'});
+ const result = highlight(str, {lang: 'js'});
result.should.eql([
'',
gutter(1, 5),
@@ -243,8 +226,8 @@ describe('highlight', function() {
validateHtmlAsync(result, done);
});
- it('auto detect of multi-line statement', function(done) {
- var str = [
+ it('auto detect of multi-line statement', done => {
+ const str = [
'"use strict";',
'var string = `',
' Multi',
@@ -253,7 +236,7 @@ describe('highlight', function() {
'`'
].join('\n');
- var result = highlight(str, {autoDetect: true});
+ const result = highlight(str, {autoDetect: true});
result.should.eql([
'',
gutter(1, 6),
@@ -263,15 +246,15 @@ describe('highlight', function() {
validateHtmlAsync(result, done);
});
- it('gives the highlight class to marked lines', function(done) {
- var str = [
+ it('gives the highlight class to marked lines', done => {
+ const str = [
'roses are red',
'violets are blue',
'sugar is sweet',
'and so are you'
].join('\n');
- var result = highlight(str, {mark: [1, 3, 5]});
+ const result = highlight(str, {mark: [1, 3, 5]});
result.should.include('class="line marked">roses');
result.should.include('class="line">violets');
@@ -281,14 +264,14 @@ describe('highlight', function() {
});
it('hljs compatibility - with lines', (done) => {
- var str = [
+ const str = [
'function (a) {',
' if (a > 3)',
' return true;',
' return false;',
'}'
].join('\n');
- var result = highlight(str, {hljs: true, lang: 'javascript' });
+ const result = highlight(str, {hljs: true, lang: 'javascript' });
result.should.include(gutterStart);
result.should.include(codeStart);
result.should.include('code class="hljs javascript"');
@@ -298,14 +281,14 @@ describe('highlight', function() {
});
it('hljs compatibility - no lines', (done) => {
- var str = [
+ const str = [
'function (a) {',
' if (a > 3)',
' return true;',
' return false;',
'}'
].join('\n');
- var result = highlight(str, {hljs: true, gutter: false, lang: 'javascript' });
+ const result = highlight(str, {hljs: true, gutter: false, lang: 'javascript' });
result.should.not.include(gutterStart);
result.should.not.include(codeStart);
result.should.include('code class="hljs javascript"');
diff --git a/test/scripts/html_tag.js b/test/scripts/html_tag.js
index b079b81e..b719d33b 100644
--- a/test/scripts/html_tag.js
+++ b/test/scripts/html_tag.js
@@ -1,15 +1,15 @@
'use strict';
-var should = require('chai').should(); // eslint-disable-line
+require('chai').should();
-describe('htmlTag', function() {
- var htmlTag = require('../../lib/html_tag');
+describe('htmlTag', () => {
+ const htmlTag = require('../../lib/html_tag');
- it('tag', function() {
+ it('tag', () => {
htmlTag('hr').should.eql('
');
});
- it('tag + attrs', function() {
+ it('tag + attrs', () => {
htmlTag('img', {
src: 'http://placekitten.com/200/300'
}).should.eql('
');
@@ -21,13 +21,41 @@ describe('htmlTag', function() {
}).should.eql('
');
});
- it('tag + attrs + text', function() {
+ it('tag + attrs + text', () => {
htmlTag('a', {
href: 'http://zespia.tw'
}, 'My blog').should.eql('My blog');
});
- it('tag is required', function() {
+ it('tag + empty ALT attr', () => {
+ htmlTag('img', {
+ src: 'http://placekitten.com/200/300',
+ alt: ''
+ }).should.eql('
');
+ });
+
+ it('passing a zero as attribute', () => {
+ htmlTag('a', {
+ href: 'http://zespia.tw',
+ tabindex: 0
+ }, 'My blog').should.eql('My blog');
+ });
+
+ it('passing a null alt attribute', () => {
+ htmlTag('a', {
+ href: 'http://zespia.tw',
+ alt: null
+ }, 'My blog').should.eql('My blog');
+ });
+
+ it('passing a undefined alt attribute', () => {
+ htmlTag('a', {
+ href: 'http://zespia.tw',
+ alt: undefined
+ }, 'My blog').should.eql('My blog');
+ });
+
+ it('tag is required', () => {
try {
htmlTag();
} catch (err) {
diff --git a/test/scripts/pattern.js b/test/scripts/pattern.js
index c57416f2..d2e99635 100644
--- a/test/scripts/pattern.js
+++ b/test/scripts/pattern.js
@@ -1,13 +1,13 @@
'use strict';
-var should = require('chai').should(); // eslint-disable-line
+require('chai').should();
-describe('Pattern', function() {
- var Pattern = require('../../lib/pattern');
+describe('Pattern', () => {
+ const Pattern = require('../../lib/pattern');
- it('String - posts/:id', function() {
- var pattern = new Pattern('posts/:id');
- var result = pattern.match('/posts/89');
+ it('String - posts/:id', () => {
+ const pattern = new Pattern('posts/:id');
+ const result = pattern.match('/posts/89');
result.should.eql({
0: 'posts/89',
@@ -16,9 +16,9 @@ describe('Pattern', function() {
});
});
- it('String - posts/*path', function() {
- var pattern = new Pattern('posts/*path');
- var result = pattern.match('posts/2013/hello-world');
+ it('String - posts/*path', () => {
+ const pattern = new Pattern('posts/*path');
+ const result = pattern.match('posts/2013/hello-world');
result.should.eql({
0: 'posts/2013/hello-world',
@@ -27,8 +27,8 @@ describe('Pattern', function() {
});
});
- it('String - posts/:id?', function() {
- var pattern = new Pattern('posts/:id?');
+ it('String - posts/:id?', () => {
+ const pattern = new Pattern('posts/:id?');
pattern.match('posts/').should.eql({
0: 'posts/',
@@ -43,15 +43,15 @@ describe('Pattern', function() {
});
});
- it('RegExp', function() {
- var pattern = new Pattern(/ab?cd/);
+ it('RegExp', () => {
+ const pattern = new Pattern(/ab?cd/);
pattern.match('abcd').should.be.ok;
pattern.match('acd').should.be.ok;
});
- it('Function', function() {
- var pattern = new Pattern(function(str) {
+ it('Function', () => {
+ const pattern = new Pattern(str => {
str.should.eql('foo');
return {};
});
@@ -59,12 +59,10 @@ describe('Pattern', function() {
pattern.match('foo').should.eql({});
});
- it('rule is required', function() {
- try {
+ it('rule is required', () => {
+ (() => {
// eslint-disable-next-line no-new
new Pattern();
- } catch (err) {
- err.should.have.property('message', 'rule must be a function, a string or a regular expression.');
- }
+ }).should.throw('rule must be a function, a string or a regular expression.');
});
});
diff --git a/test/scripts/permalink.js b/test/scripts/permalink.js
index a78717da..4ce6a6e2 100644
--- a/test/scripts/permalink.js
+++ b/test/scripts/permalink.js
@@ -1,12 +1,12 @@
'use strict';
-var should = require('chai').should(); // eslint-disable-line
+require('chai').should();
-describe('Permalink', function() {
- var Permalink = require('../../lib/permalink');
- var permalink;
+describe('Permalink', () => {
+ const Permalink = require('../../lib/permalink');
+ let permalink;
- it('constructor', function() {
+ it('constructor', () => {
permalink = new Permalink(':year/:month/:day/:title');
permalink.rule.should.eql(':year/:month/:day/:title');
@@ -26,7 +26,7 @@ describe('Permalink', function() {
permalink.params.should.eql(['year', 'month', 'day', 'title']);
});
- it('rule is required', function() {
+ it('rule is required', () => {
try {
// eslint-disable-next-line no-new
new Permalink();
@@ -35,12 +35,12 @@ describe('Permalink', function() {
}
});
- it('test()', function() {
+ it('test()', () => {
permalink.test('2014/01/31/test').should.be.true;
permalink.test('foweirojwoier').should.be.false;
});
- it('parse()', function() {
+ it('parse()', () => {
permalink.parse('2014/01/31/test').should.eql({
year: '2014',
month: '01',
@@ -49,7 +49,7 @@ describe('Permalink', function() {
});
});
- it('stringify()', function() {
+ it('stringify()', () => {
permalink.stringify({
year: '2014',
month: '01',
diff --git a/test/scripts/slugize.js b/test/scripts/slugize.js
index 324f859a..d1db5442 100644
--- a/test/scripts/slugize.js
+++ b/test/scripts/slugize.js
@@ -1,51 +1,47 @@
'use strict';
-var should = require('chai').should(); // eslint-disable-line
+require('chai').should();
-describe('slugize', function() {
- var slugize = require('../../lib/slugize');
+describe('slugize', () => {
+ const slugize = require('../../lib/slugize');
- it('spaces', function() {
+ it('spaces', () => {
slugize('Hello World').should.eql('Hello-World');
});
- it('diacritic', function() {
+ it('diacritic', () => {
slugize('Hell\u00F2 w\u00F2rld').should.eql('Hello-world');
});
- it('continous dashes', function() {
+ it('continous dashes', () => {
slugize('Hello World').should.eql('Hello-World');
});
- it('prefixing and trailing dashes', function() {
+ it('prefixing and trailing dashes', () => {
slugize('~Hello World~').should.eql('Hello-World');
});
- it('other special characters', function() {
+ it('other special characters', () => {
slugize('Hello ~`!@#$%^&*()-_+=[]{}|\\;:"\'<>,.?/World').should.eql('Hello-World');
});
- it('custom separator', function() {
+ it('custom separator', () => {
slugize('Hello World', {separator: '_'}).should.eql('Hello_World');
});
- it('lower case', function() {
+ it('lower case', () => {
slugize('Hello World', {transform: 1}).should.eql('hello-world');
});
- it('upper case', function() {
+ it('upper case', () => {
slugize('Hello World', {transform: 2}).should.eql('HELLO-WORLD');
});
- it('non-english', function() {
+ it('non-english', () => {
slugize('遊戲').should.eql('遊戲');
});
- it('str must be a string', function() {
- try {
- slugize();
- } catch (err) {
- err.should.have.property('message', 'str must be a string!');
- }
+ it('str must be a string', () => {
+ slugize.should.throw('str must be a string!');
});
});
diff --git a/test/scripts/spawn.js b/test/scripts/spawn.js
index 4e8cb13e..7d21e909 100644
--- a/test/scripts/spawn.js
+++ b/test/scripts/spawn.js
@@ -1,96 +1,96 @@
'use strict';
-var should = require('chai').should(); // eslint-disable-line
-var pathFn = require('path');
-var fs = require('fs');
-var rewire = require('rewire');
-
-describe('spawn', function() {
- var spawn = require('../../lib/spawn');
- var CacheStream = require('../../lib/cache_stream');
- var fixturePath = pathFn.join(__dirname, 'spawn_test.txt');
- var fixture = 'test content';
-
- before(function(done) {
- fs.writeFile(fixturePath, fixture, done);
+require('chai').use(require('chai-as-promised')).should();
+const { join } = require('path');
+const { writeFile, unlink } = require('fs');
+const rewire = require('rewire');
+
+const isWindows = process.platform === 'win32';
+const catCommand = isWindows ? 'type' : 'cat';
+
+describe('spawn', () => {
+ const spawn = require('../../lib/spawn');
+ const CacheStream = require('../../lib/cache_stream');
+ const fixturePath = join(__dirname, 'spawn_test.txt');
+ const fixture = 'test content';
+
+ before(done => {
+ writeFile(fixturePath, fixture, done);
});
- after(function(done) {
- fs.unlink(fixturePath, done);
+ after(done => {
+ unlink(fixturePath, done);
});
- it('default', function() {
- return spawn('cat', [fixturePath]).then(function(content) {
- content.should.eql(fixture);
- });
- });
+ it('default', () => spawn(catCommand, [fixturePath]).should.become(fixture));
- it('command is required', function() {
- try {
- spawn();
- } catch (err) {
- err.should.have.property('message', 'command is required!');
- }
+ it('command is required', () => {
+ spawn.should.throw('command is required!');
});
- it('error', function() {
- return spawn('cat', ['nothing']).catch(function(err) {
- err.message.trim().should.eql('cat: nothing: No such file or directory');
- err.code.should.eql(1);
- });
+ it('error', () => {
+ const promise = spawn(catCommand, ['nothing']);
+ if (isWindows) {
+ return promise.should.rejectedWith('spawn type ENOENT').and.eventually.have.property('code', 'ENOENT');
+ }
+ return promise.should.rejectedWith('cat: nothing: No such file or directory').and.eventually.have.property('code', 1);
});
- it('verbose - stdout', function() {
- var spawn = rewire('../../lib/spawn');
- var stdoutCache = new CacheStream();
- var stderrCache = new CacheStream();
- var content = 'something';
+ it('verbose - stdout', () => {
+ const spawn = rewire('../../lib/spawn');
+ const stdoutCache = new CacheStream();
+ const stderrCache = new CacheStream();
+ const content = 'something';
- spawn.__set__('process', {
+ spawn.__set__('process', Object.assign({}, process, {
stdout: stdoutCache,
stderr: stderrCache
- });
+ }));
return spawn('echo', [content], {
verbose: true
- }).then(function() {
- stdoutCache.getCache().toString('utf8').trim().should.eql(content);
+ }).then(() => {
+ const result = stdoutCache.getCache().toString('utf8').trim();
+ if (isWindows) {
+ result.should.match(new RegExp(`^(["']?)${content}\\1$`));
+ } else {
+ result.should.eql(content);
+ }
});
});
- it('verbose - stderr', function() {
- var spawn = rewire('../../lib/spawn');
- var stdoutCache = new CacheStream();
- var stderrCache = new CacheStream();
+ it('verbose - stderr', () => {
+ const spawn = rewire('../../lib/spawn');
+ const stdoutCache = new CacheStream();
+ const stderrCache = new CacheStream();
- spawn.__set__('process', {
+ spawn.__set__('process', Object.assign({}, process, {
stdout: stdoutCache,
- stderr: stderrCache
- });
+ stderr: stderrCache,
+ removeListener: () => {},
+ on: () => {}
+ }));
- return spawn('cat', ['nothing'], {
+ return spawn(catCommand, ['nothing'], {
verbose: true
- }).catch(function() {
- stderrCache.getCache().toString('utf8').trim().should
- .eql('cat: nothing: No such file or directory');
+ }).should.rejected.then(() => {
+ const stderrResult = stderrCache.getCache();
+ if (isWindows) {
+ // utf8 support in windows shell (cmd.exe) is difficult.
+ Buffer.byteLength(stderrResult, 'hex').should.least(1);
+ } else {
+ stderrResult.toString('utf8').should.with.match(/^cat: nothing: No such file or directory\n?$/);
+ }
});
});
- it('custom encoding', function() {
- return spawn('cat', [fixturePath], {encoding: 'hex'}).then(function(content) {
- content.should.eql(Buffer.from(fixture).toString('hex'));
- });
+ it('custom encoding', () => {
+ return spawn(catCommand, [fixturePath], {encoding: 'hex'}).should.become(Buffer.from(fixture).toString('hex'));
});
- it('encoding = null', function() {
- return spawn('cat', [fixturePath], {encoding: null}).then(function(content) {
- content.should.eql(Buffer.from(fixture));
- });
+ it('encoding = null', () => {
+ return spawn(catCommand, [fixturePath], {encoding: null}).should.become(Buffer.from(fixture));
});
- it('stdio = inherit', function() {
- return spawn('echo', ['something'], {
- stdio: 'inherit'
- });
- });
+ it('stdio = inherit', () => spawn('echo', ['something'], { stdio: 'inherit' }));
});
diff --git a/test/scripts/truncate.js b/test/scripts/truncate.js
index cc29b062..67a1cb2d 100644
--- a/test/scripts/truncate.js
+++ b/test/scripts/truncate.js
@@ -1,40 +1,36 @@
'use strict';
-var should = require('chai').should(); // eslint-disable-line
+require('chai').should();
-describe('truncate', function() {
- var truncate = require('../../lib/truncate');
+describe('truncate', () => {
+ const truncate = require('../../lib/truncate');
- it('default', function() {
+ it('default', () => {
truncate('Once upon a time in a world far far away')
.should.eql('Once upon a time in a world...');
});
- it('shorter string', function() {
+ it('shorter string', () => {
truncate('Once upon')
.should.eql('Once upon');
});
- it('truncate', function() {
+ it('truncate', () => {
truncate('Once upon a time in a world far far away', {length: 17})
.should.eql('Once upon a ti...');
});
- it('separator', function() {
+ it('separator', () => {
truncate('Once upon a time in a world far far away', {length: 17, separator: ' '})
.should.eql('Once upon a...');
});
- it('omission', function() {
+ it('omission', () => {
truncate('And they found that many people were sleeping better.', {length: 25, omission: '... (continued)'})
.should.eql('And they f... (continued)');
});
- it('str must be a string', function() {
- try {
- truncate();
- } catch (err) {
- err.should.have.property('message', 'str must be a string!');
- }
+ it('str must be a string', () => {
+ truncate.should.throw('str must be a string!');
});
});
diff --git a/test/scripts/word_wrap.js b/test/scripts/word_wrap.js
index ec89aed3..0da8242f 100644
--- a/test/scripts/word_wrap.js
+++ b/test/scripts/word_wrap.js
@@ -1,32 +1,28 @@
'use strict';
-var should = require('chai').should(); // eslint-disable-line
+require('chai').should();
-describe('wordWrap', function() {
- var wordWrap = require('../../lib/word_wrap');
+describe('wordWrap', () => {
+ const wordWrap = require('../../lib/word_wrap');
- it('default', function() {
+ it('default', () => {
wordWrap('Once upon a time').should.eql('Once upon a time');
});
- it('default width', function() {
+ it('default width', () => {
wordWrap('Once upon a time, in a kingdom called Far Far Away, a king fell ill, and finding a successor to the throne turned out to be more trouble than anyone could have imagined...')
.should.eql('Once upon a time, in a kingdom called Far Far Away, a king fell ill, and finding\na successor to the throne turned out to be more trouble than anyone could have\nimagined...');
});
- it('width = 8', function() {
+ it('width = 8', () => {
wordWrap('Once upon a time', {width: 8}).should.eql('Once\nupon a\ntime');
});
- it('width = 1', function() {
+ it('width = 1', () => {
wordWrap('Once upon a time', {width: 1}).should.eql('Once\nupon\na\ntime');
});
- it('str must be a string', function() {
- try {
- wordWrap();
- } catch (err) {
- err.should.have.property('message', 'str must be a string!');
- }
+ it('str must be a string', () => {
+ wordWrap.should.throw('str must be a string!');
});
});