From 679dcaf077912e86bffa33e82a413cf19b9fe942 Mon Sep 17 00:00:00 2001 From: curbengh <43627182+curbengh@users.noreply.github.com> Date: Thu, 26 Dec 2019 11:11:36 +0000 Subject: [PATCH] test: add tests for html, js, css minifiers --- .gitignore | 1 + .travis.yml | 7 +- index.js | 52 ++++++++------ package.json | 15 +++++ test/filter.test.js | 160 ++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 211 insertions(+), 24 deletions(-) create mode 100644 test/filter.test.js diff --git a/.gitignore b/.gitignore index d499829..a6d9d63 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ node_modules/ package-lock.json tmp/ *.log +coverage/ diff --git a/.travis.yml b/.travis.yml index 2e8214e..ee7b5bc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,15 +10,16 @@ cache: npm: true script: + - npm run lint + - npm run test + +after_script: - npm install snyk - snyk auth $SNYK_TOKEN - snyk test # Check node modules for vulnerability - snyk protect # Patch node modules (if available) - snyk monitor # Update dependencies to snyk - - npm install standard - - standard - branches: only: - master # Only build master branch diff --git a/index.js b/index.js index 4583aee..863f9b1 100644 --- a/index.js +++ b/index.js @@ -1,11 +1,8 @@ /* global hexo */ 'use strict' -hexo.config.minify = Object.assign({ - enable: true -}, hexo.config.minify) - -hexo.config.minify.html = Object.assign({ +const minifyDefault = { enable: true } +const htmlDefault = { enable: true, priority: 10, logger: false, @@ -21,9 +18,8 @@ hexo.config.minify.html = Object.assign({ minifyJS: true, minifyCSS: true, globOptions: { basename: true } -}, hexo.config.minify.html) - -hexo.config.minify.css = Object.assign({ +} +const cssDefault = { enable: true, priority: 10, // TODO: rename to verbose @@ -31,9 +27,8 @@ hexo.config.minify.css = Object.assign({ exclude: ['*.min.css'], level: 2, globOptions: { basename: true } -}, hexo.config.minify.css) - -hexo.config.minify.js = Object.assign({ +} +const jsDefault = { enable: true, priority: 10, logger: false, @@ -42,32 +37,37 @@ hexo.config.minify.js = Object.assign({ mangle: true, output: {}, globOptions: { basename: true } -}, hexo.config.minify.js) - -hexo.config.minify.svg = Object.assign({ +} +const svgDefault = { enable: true, priority: 10, logger: false, include: ['*.svg', '!*.min.svg'], plugins: [], globOptions: { basename: true } -}, hexo.config.minify.svg) - -hexo.config.minify.gzip = Object.assign({ +} +const gzipDefault = { enable: true, priority: 10, logger: false, include: ['*.html', '*.css', '*.js', '*.txt', '*.ttf', '*.atom', '*.stl', '*.xml', '*.svg', '*.eot', '*.json'], globOptions: { basename: true } -}, hexo.config.minify.gzip) - -hexo.config.minify.brotli = Object.assign({ +} +const brotliDefault = { enable: true, priority: 10, logger: false, include: ['*.html', '*.css', '*.js', '*.txt', '*.ttf', '*.atom', '*.stl', '*.xml', '*.svg', '*.eot', '*.json'], globOptions: { basename: true } -}, hexo.config.minify.brotli) +} + +hexo.config.minify = Object.assign(minifyDefault, hexo.config.minify) +hexo.config.minify.html = Object.assign(htmlDefault, hexo.config.minify.html) +hexo.config.minify.css = Object.assign(cssDefault, hexo.config.minify.css) +hexo.config.minify.js = Object.assign(jsDefault, hexo.config.minify.js) +hexo.config.minify.svg = Object.assign(svgDefault, hexo.config.minify.svg) +hexo.config.minify.gzip = Object.assign(gzipDefault, hexo.config.minify.gzip) +hexo.config.minify.brotli = Object.assign(brotliDefault, hexo.config.minify.brotli) if (hexo.config.minify.enable === true) { const filter = require('./lib/filter') @@ -78,3 +78,13 @@ if (hexo.config.minify.enable === true) { hexo.extend.filter.register('after_generate', filter.gzipFn, hexo.config.minify.gzip.priority) hexo.extend.filter.register('after_generate', filter.brotliFn, hexo.config.minify.brotli.priority) } + +module.exports = { + minifyDefault, + htmlDefault, + cssDefault, + jsDefault, + svgDefault, + gzipDefault, + brotliDefault +} diff --git a/package.json b/package.json index 7828a5c..bae236a 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,10 @@ "lib/", "index.js" ], + "scripts": { + "lint": "standard", + "test": "jest test/filter.test.js" + }, "engines": { "node": ">= 8.6.0" }, @@ -26,6 +30,11 @@ "svgo": "^1.2.2", "terser": "^4.0.0" }, + "devDependencies": { + "hexo": "^4.2.0", + "jest": "^24.9.0", + "standard": "^14.3.1" + }, "keywords": [ "html", "js", @@ -38,6 +47,12 @@ "hexo-yam", "hexo" ], + "jest": { + "clearMocks": true, + "collectCoverage": true, + "coverageDirectory": "coverage", + "testEnvironment": "node" + }, "greenkeeper": { "commitMessages": { "initialBadge": "docs(readme): Add Greenkeeper badge", diff --git a/test/filter.test.js b/test/filter.test.js new file mode 100644 index 0000000..575a412 --- /dev/null +++ b/test/filter.test.js @@ -0,0 +1,160 @@ +/* eslint-env jest */ +'use strict' + +const Hexo = require('hexo') +const hexo = new Hexo(__dirname) +global.hexo = hexo + +describe('html', () => { + const { htmlDefault } = require('../index') + const h = require('../lib/filter').minifyHtml.bind(hexo) + const Htmlminifier = require('html-minifier').minify + + beforeEach(() => { + hexo.config.minify.html = htmlDefault + }) + + test('default', () => { + const input = '

foo

' + const result = h(input, { path: '' }) + const expected = Htmlminifier(input, hexo.config.minify.html) + expect(result).toBe(expected) + }) + + test('option', () => { + const customOpt = { removeEmptyAttributes: false } + hexo.config.minify.html = customOpt + + const input = '

foo

' + const result = h(input, { path: '' }) + const expected = Htmlminifier(input, customOpt) + expect(result).toBe(input) + expect(result).toBe(expected) + }) + + test('exclude', () => { + const exclude = '*.min.html' + hexo.config.minify.html.exclude = exclude + + const input = '

foo

' + const result = h(input, { path: 'foo/bar.min.html' }) + expect(result).toBe(input) + }) + + test('exclude - slash in pattern', () => { + const exclude = '**/bar.html' + hexo.config.minify.html.exclude = exclude + + const input = '

foo

' + const result = h(input, { path: 'foo/bar.html' }) + expect(result).toBe(input) + }) +}) + +describe('css', () => { + const { cssDefault } = require('../index') + const c = require('../lib/filter').minifyCss.bind(hexo) + const CleanCSS = require('clean-css') + + beforeEach(() => { + hexo.config.minify.css = cssDefault + }) + + test('default', async () => { + const input = 'foo { bar: baz; } foo { aaa: bbb; }' + const result = await c(input, { path: '' }) + const { styles } = await new CleanCSS(hexo.config.minify.css).minify(input) + expect(result).toBe(styles) + }) + + test('option', async () => { + const customOpt = { + level: { + 1: { + mergeAdjacentRules: false + } + } + } + hexo.config.minify.css = customOpt + + const input = 'foo { bar: baz; } foo { aaa: bbb; }' + const result = await c(input, { path: '' }) + const { styles } = await new CleanCSS(customOpt).minify(input) + expect(result).toBe(styles) + }) + + test('exclude - *.min.css', async () => { + const input = 'foo { bar: baz; } foo { aaa: bbb; }' + const result = await c(input, { path: 'foo/bar.min.css' }) + expect(result).toBe(input) + }) + + test('exclude - basename', async () => { + const exclude = '*baz.css' + hexo.config.minify.css.exclude = exclude + const input = 'foo { bar: baz; } foo { aaa: bbb; }' + const result = await c(input, { path: 'foo/barbaz.css' }) + expect(result).toBe(input) + }) + + test('exclude - slash in pattern', async () => { + const exclude = '**/bar.css' + hexo.config.minify.css.exclude = exclude + const input = 'foo { bar: baz; } foo { aaa: bbb; }' + const result = await c(input, { path: 'foo/bar.css' }) + expect(result).toBe(input) + }) +}) + +describe('js', () => { + const { jsDefault } = require('../index') + const j = require('../lib/filter').minifyJs.bind(hexo) + const Terser = require('terser') + + beforeEach(() => { + hexo.config.minify.js = jsDefault + }) + + test('default', () => { + const input = 'var o = { "foo": 1, bar: 3 };' + const result = j(input, { path: '' }) + const { code } = Terser.minify(input, { mangle: jsDefault.mangle }) + expect(result).toBe(code) + }) + + test('option', () => { + const customOpt = { + mangle: { + properties: true + } + } + hexo.config.minify.js = customOpt + + const input = 'var o = { "foo": 1, bar: 3 };' + const result = j(input, { path: '' }) + const { code } = Terser.minify(input, customOpt) + expect(result).toBe(code) + }) + + test('exclude - *.min.js', () => { + const input = 'var o = { "foo": 1, bar: 3 };' + const result = j(input, { path: 'foo/bar.min.js' }) + expect(result).toBe(input) + }) + + test('exclude - basename', () => { + const exclude = '*baz.js' + hexo.config.minify.js.exclude = exclude + const input = 'var o = { "foo": 1, bar: 3 };' + const result = j(input, { path: 'foo/barbaz.js' }) + expect(result).toBe(input) + }) + + test('exclude - slash in pattern', () => { + const exclude = '**/bar.js' + hexo.config.minify.js.exclude = exclude + const input = 'var o = { "foo": 1, bar: 3 };' + const result = j(input, { path: 'foo/bar.js' }) + expect(result).toBe(input) + }) +})