From 427c04601e0f56add722c9abccc22ab2cf7fbdea Mon Sep 17 00:00:00 2001 From: Aileen Nowak Date: Fri, 17 Nov 2017 16:46:21 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=97=9C=20=20Added=20eslint=20(#104)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit no issue --- .eslintrc.json | 300 +++++++++++++++ lib/amperize.js | 426 ++++++++++----------- lib/helpers.js | 44 ++- test/.eslintrc.json | 238 ++++++++++++ test/amperize.test.js | 841 +++++++++++++++++++++--------------------- test/helpers.test.js | 150 ++++---- 6 files changed, 1269 insertions(+), 730 deletions(-) create mode 100644 .eslintrc.json create mode 100644 test/.eslintrc.json diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..09e8732 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,300 @@ +{ + "env": { + "es6": true, + "node": true + }, + "extends": "eslint:recommended", + "rules": { + "accessor-pairs": "error", + "array-bracket-newline": "off", + "array-bracket-spacing": [ + "error", + "never" + ], + "array-callback-return": "off", + "array-element-newline": "off", + "arrow-body-style": "error", + "arrow-parens": [ + "error", + "always" + ], + "arrow-spacing": [ + "error", + { + "after": true, + "before": true + } + ], + "block-scoped-var": "error", + "brace-style": [ + "error", + "1tbs", + { + "allowSingleLine": true + } + ], + "callback-return": "error", + "camelcase": [ + "error", + { + "properties": "never" + } + ], + "capitalized-comments": "off", + "class-methods-use-this": "off", + "comma-dangle": "error", + "comma-spacing": "error", + "comma-style": [ + "error", + "last" + ], + "complexity": "off", + "computed-property-spacing": [ + "error", + "never" + ], + "consistent-return": "off", + "consistent-this": "off", + "curly": "error", + "default-case": "error", + "dot-location": [ + "error", + "property" + ], + "dot-notation": "error", + "eol-last": "error", + "eqeqeq": "error", + "for-direction": "error", + "func-call-spacing": "error", + "func-name-matching": "off", + "func-names": "off", + "func-style": "off", + "function-paren-newline": "off", + "generator-star-spacing": "error", + "getter-return": "error", + "global-require": "off", + "guard-for-in": "error", + "handle-callback-err": "error", + "id-blacklist": "error", + "id-length": "off", + "id-match": "error", + "indent": [ + "error", + 4, + { + "SwitchCase": 1 + } + ], + "indent-legacy": "off", + "init-declarations": "off", + "jsx-quotes": "error", + "key-spacing": "error", + "keyword-spacing": "error", + "line-comment-position": "off", + "linebreak-style": [ + "error", + "unix" + ], + "lines-around-comment": "off", + "lines-around-directive": "off", + "lines-between-class-members": [ + "error", + "always" + ], + "max-depth": "error", + "max-len": "off", + "max-lines": "off", + "max-nested-callbacks": "error", + "max-params": "off", + "max-statements": "off", + "max-statements-per-line": "off", + "multiline-comment-style": "off", + "multiline-ternary": "off", + "new-parens": "error", + "newline-after-var": "off", + "newline-before-return": "off", + "newline-per-chained-call": "off", + "no-alert": "error", + "no-array-constructor": "error", + "no-await-in-loop": "error", + "no-bitwise": "off", + "no-buffer-constructor": "off", + "no-caller": "error", + "no-catch-shadow": "error", + "no-confusing-arrow": "error", + "no-continue": "error", + "no-div-regex": "off", + "no-duplicate-imports": "error", + "no-else-return": "off", + "no-empty-function": "off", + "no-eq-null": "error", + "no-eval": "error", + "no-extend-native": "error", + "no-extra-bind": "error", + "no-extra-label": "error", + "no-extra-parens": "off", + "no-floating-decimal": "error", + "no-implicit-globals": "error", + "no-implied-eval": "error", + "no-inline-comments": "off", + "no-inner-declarations": [ + "error", + "functions" + ], + "no-invalid-this": "error", + "no-iterator": "error", + "no-label-var": "error", + "no-labels": "error", + "no-lone-blocks": "error", + "no-lonely-if": "off", + "no-loop-func": "error", + "no-magic-numbers": "off", + "no-mixed-operators": "off", + "no-mixed-requires": "off", + "no-multi-assign": "off", + "no-multi-spaces": "off", + "no-multi-str": "error", + "no-multiple-empty-lines": ["error", {"max": 1}], + "no-native-reassign": "error", + "no-negated-condition": "off", + "no-negated-in-lhs": "error", + "no-nested-ternary": "off", + "no-new": "error", + "no-new-func": "error", + "no-new-object": "error", + "no-new-require": "error", + "no-new-wrappers": "error", + "no-octal-escape": "error", + "no-param-reassign": "off", + "no-path-concat": "off", + "no-plusplus": "error", + "no-process-env": "off", + "no-process-exit": "off", + "no-proto": "error", + "no-prototype-builtins": "off", + "no-restricted-globals": "error", + "no-restricted-imports": "error", + "no-restricted-modules": "error", + "no-restricted-properties": "error", + "no-restricted-syntax": "error", + "no-return-assign": "error", + "no-return-await": "error", + "no-script-url": "error", + "no-self-compare": "error", + "no-sequences": "error", + "no-shadow": "off", + "no-shadow-restricted-names": "error", + "no-spaced-func": "error", + "no-sync": "off", + "no-tabs": "error", + "no-template-curly-in-string": "error", + "no-ternary": "off", + "no-throw-literal": "error", + "no-trailing-spaces": "error", + "no-undef-init": "error", + "no-undefined": "off", + "no-underscore-dangle": "off", + "no-unmodified-loop-condition": "error", + "no-unneeded-ternary": "off", + "no-use-before-define": "off", + "no-useless-call": "error", + "no-useless-computed-key": "error", + "no-useless-concat": "off", + "no-useless-constructor": "error", + "no-useless-escape": "off", + "no-useless-rename": "error", + "no-useless-return": "error", + "no-var": "off", + "no-void": "error", + "no-warning-comments": "off", + "no-whitespace-before-property": "error", + "no-with": "error", + "nonblock-statement-body-position": "error", + "object-curly-newline": [ + "error", + { + "consistent": true + } + ], + "object-curly-spacing": [ + "error", + "never" + ], + "object-property-newline": [ + "error", + { + "allowMultiplePropertiesPerLine": true + } + ], + "object-shorthand": "off", + "one-var": "off", + "one-var-declaration-per-line": "off", + "operator-assignment": "off", + "operator-linebreak": "off", + "padded-blocks": [ + "error", + "never" + ], + "padding-line-between-statements": "error", + "prefer-arrow-callback": "off", + "prefer-const": "off", + "prefer-destructuring": "off", + "prefer-numeric-literals": "error", + "prefer-promise-reject-errors": "off", + "prefer-reflect": "off", + "prefer-rest-params": "off", + "prefer-spread": "off", + "prefer-template": "off", + "quote-props": [ + "error", + "as-needed" + ], + "quotes": ["error", "single"], + "radix": "off", + "require-await": "error", + "require-jsdoc": "off", + "rest-spread-spacing": "error", + "semi": ["error", "always"], + "semi-spacing": "error", + "semi-style": [ + "error", + "last" + ], + "sort-imports": "error", + "sort-keys": "off", + "sort-vars": "off", + "space-before-blocks": "error", + "space-before-function-paren": [ + "error", + { + "anonymous": "always", + "named": "never" + } + ], + "space-in-parens": [ + "error", + "never" + ], + "space-infix-ops": "error", + "space-unary-ops": "error", + "spaced-comment": "error", + "strict": "off", + "switch-colon-spacing": "error", + "symbol-description": "error", + "template-curly-spacing": [ + "error", + "never" + ], + "template-tag-spacing": "error", + "unicode-bom": [ + "error", + "never" + ], + "valid-jsdoc": "off", + "vars-on-top": "off", + "wrap-iife": "off", + "wrap-regex": "off", + "yield-star-spacing": "error", + "yoda": "error" + } +} diff --git a/lib/amperize.js b/lib/amperize.js index 9778594..889a2b3 100644 --- a/lib/amperize.js +++ b/lib/amperize.js @@ -1,259 +1,265 @@ 'use strict'; -var EventEmitter = require('events').EventEmitter - , emits = require('emits') - , html = require('htmlparser2') - , util = require('util') - , uuid = require('uuid') - , async = require('async') - , url = require('url') - , got = require('got') - , _ = require('lodash') - , sizeOf = require('image-size') - , validator = require('validator') - , helpers = require('./helpers'); - -var DEFAULTS = { - 'amp-img': { - layout: 'responsive', - width: 600, - height: 400, - }, - 'amp-anim': { - layout: 'responsive', - width: 600, - height: 400, - }, - 'amp-iframe': { - layout: 'responsive', - width: 600, - height: 400, - sandbox: 'allow-scripts allow-same-origin' - } -}; +var EventEmitter = require('events').EventEmitter, + emits = require('emits'), + html = require('htmlparser2'), + util = require('util'), + uuid = require('uuid'), + async = require('async'), + url = require('url'), + got = require('got'), + _ = require('lodash'), + sizeOf = require('image-size'), + validator = require('validator'), + helpers = require('./helpers'), + DEFAULTS = { + 'amp-img': { + layout: 'responsive', + width: 600, + height: 400 + }, + 'amp-anim': { + layout: 'responsive', + width: 600, + height: 400 + }, + 'amp-iframe': { + layout: 'responsive', + width: 600, + height: 400, + sandbox: 'allow-scripts allow-same-origin' + } + }; /** - * Amperizer constructor. Borrows from Minimize. - * - * https://github.com/Swaagie/minimize/blob/4b815e274a424ca89551d28c4e0dd8b06d9bbdc2/lib/minimize.js#L15 - * - * @constructor - * @param {Object} options Options object - * @api public - */ +* Amperizer constructor. Borrows from Minimize. +* +* https://github.com/Swaagie/minimize/blob/4b815e274a424ca89551d28c4e0dd8b06d9bbdc2/lib/minimize.js#L15 +* +* @constructor +* @param {Object} options Options object +* @api public +*/ function Amperize(options) { - this.config = _.merge({}, DEFAULTS, options || {}); - this.emits = emits; + this.config = _.merge({}, DEFAULTS, options || {}); + this.emits = emits; - this.htmlParser = new html.Parser( - new html.DomHandler(this.emits('read')) - ); + this.htmlParser = new html.Parser( + new html.DomHandler(this.emits('read')) + ); } util.inherits(Amperize, EventEmitter); /** - * Parse the content and call the callback. Borrowed from Minimize. - * - * https://github.com/Swaagie/minimize/blob/4b815e274a424ca89551d28c4e0dd8b06d9bbdc2/lib/minimize.js#L51 - * - * @param {String} content HTML - * @param {Function} callback - * @api public - */ +* Parse the content and call the callback. Borrowed from Minimize. +* +* https://github.com/Swaagie/minimize/blob/4b815e274a424ca89551d28c4e0dd8b06d9bbdc2/lib/minimize.js#L51 +* +* @param {String} content HTML +* @param {Function} callback +* @api public +*/ Amperize.prototype.parse = function parse(content, callback) { - if (typeof callback !== 'function') throw new Error('No callback provided'); - var id = uuid.v4(); + var id; - this.once('read', this.amperizer.bind(this, id)); - this.once('parsed: ' + id, callback); + if (typeof callback !== 'function') { + throw new Error('No callback provided'); + } - this.htmlParser.parseComplete(content); + id = uuid.v4(); + + this.once('read', this.amperizer.bind(this, id)); + this.once('parsed: ' + id, callback); + + this.htmlParser.parseComplete(content); }; /** - * Turn a traversible DOM into string content. Borrowed from Minimize. - * - * https://github.com/Swaagie/minimize/blob/4b815e274a424ca89551d28c4e0dd8b06d9bbdc2/lib/minimize.js#L74 - * - * @param {Object} error - * @param {Object} dom Traversible DOM object - * @api private - */ +* Turn a traversible DOM into string content. Borrowed from Minimize. +* +* https://github.com/Swaagie/minimize/blob/4b815e274a424ca89551d28c4e0dd8b06d9bbdc2/lib/minimize.js#L74 +* +* @param {String} id +* @param {Object} error +* @param {Object} dom Traversible DOM object +* @api private +*/ Amperize.prototype.amperizer = function amperizer(id, error, dom) { - if (error) throw new Error('Amperizer failed to parse DOM', error); + if (error) { + throw new Error('Amperizer failed to parse DOM', error); + } - this.traverse(dom, '', this.emits('parsed: ' + id)); + this.traverse(dom, '', this.emits('parsed: ' + id)); }; /** - * Reduce the traversible DOM object to a string. Borrows from Minimize. - * - * https://github.com/Swaagie/minimize/blob/4b815e274a424ca89551d28c4e0dd8b06d9bbdc2/lib/minimize.js#L90 - * - * @param {Array} data - * @param {String} html Compiled HTML contents - * @param {Function} done Callback function - * @api private - */ +* Reduce the traversible DOM object to a string. Borrows from Minimize. +* +* https://github.com/Swaagie/minimize/blob/4b815e274a424ca89551d28c4e0dd8b06d9bbdc2/lib/minimize.js#L90 +* +* @param {Array} data +* @param {String} html Compiled HTML contents +* @param {Function} done Callback function +* @api private +*/ Amperize.prototype.traverse = function traverse(data, html, done) { - var amperize = this; + var self = this; - async.reduce(data, html, function reduce(html, element, step) { - var children; + async.reduce(data, html, function reduce(html, element, step) { + var children; - function close(error, html) { - html += helpers.close(element); - step(null, html); - } - - function enter(error) { - children = element.children; - html += helpers[element.type](element); - - if (!children || !children.length) return close(null, html); - - setImmediate(function delay() { - traverse.call(amperize, children, html, close); - }); - } - - function useSecureSchema(element) { - if (element.attribs && element.attribs.src) { - // Every src attribute must be with 'https' protocol otherwise it will not get validated by AMP. - // If we're unable to replace it, we will deal with the valitation error, but at least - // we tried. - if (element.attribs.src.indexOf('https://') === -1) { - if (element.attribs.src.indexOf('http://') === 0) { - // Replace 'http' with 'https', so the validation passes - element.attribs.src = element.attribs.src.replace(/^http:\/\//i, 'https://'); - } else if (element.attribs.src.indexOf('//') === 0) { - // Giphy embedded iFrames are without protocol and start with '//', so at least - // we can fix those cases. - element.attribs.src = 'https:' + element.attribs.src; - } + function close(error, html) { + html += helpers.close(element); + step(null, html); } - } - return; - } + function enter() { + children = element.children; + html += helpers[element.type](element); - function getLayoutAttribute(element) { - var layout; + if (!children || !children.length) { + return close(null, html); + } - // check if element.width is smaller than 300 px. In that case, we shouldn't use - // layout="responsive", because the media element will be stretched and it doesn't - // look nice. Use layout="fixed" instead to fix that. - layout = element.attribs.width < 300 ? layout = 'fixed' : amperize.config[element.name].layout; + setImmediate(function delay() { + traverse.call(self, children, html, close); + }); + } - element.attribs.layout = !element.attribs.layout ? layout : element.attribs.layout; + function useSecureSchema(element) { + if (element.attribs && element.attribs.src) { + // Every src attribute must be with 'https' protocol otherwise it will not get validated by AMP. + // If we're unable to replace it, we will deal with the valitation error, but at least + // we tried. + if (element.attribs.src.indexOf('https://') === -1) { + if (element.attribs.src.indexOf('http://') === 0) { + // Replace 'http' with 'https', so the validation passes + element.attribs.src = element.attribs.src.replace(/^http:\/\//i, 'https://'); + } else if (element.attribs.src.indexOf('//') === 0) { + // Giphy embedded iFrames are without protocol and start with '//', so at least + // we can fix those cases. + element.attribs.src = 'https:' + element.attribs.src; + } + } + } + } - return enter(); - } + function getLayoutAttribute(element) { + var layout; - /** - * Get the image sizes (width and heigth plus type of image) - * - * https://github.com/image-size/image-size - * - * @param {Object} element - * @return {Object} element incl. width and height - */ - function getImageSize(element) { - var imageObj = url.parse(element.attribs.src), - requestOptions, - timeout = 3000; - - if (!validator.isURL(imageObj.href)) { - // revert this element, do not show - element.name = 'img'; + // check if element.width is smaller than 300 px. In that case, we shouldn't use + // layout="responsive", because the media element will be stretched and it doesn't + // look nice. Use layout="fixed" instead to fix that. + layout = element.attribs.width < 300 ? layout = 'fixed' : self.config[element.name].layout; - return enter(); - } + element.attribs.layout = !element.attribs.layout ? layout : element.attribs.layout; - // We need the user-agent, otherwise some https request may fail (e. g. cloudfare) - requestOptions = { - headers: { - 'User-Agent': 'Mozilla/5.0' - }, - timeout: timeout, - encoding: null - }; - - return got ( - imageObj.href, - requestOptions - ).then(function (response) { - try { - // Using the Buffer rather than an URL requires to use sizeOf synchronously. - // See https://github.com/image-size/image-size#asynchronous - var dimensions = sizeOf(response.body); - - // CASE: `.ico` files might have multiple images and therefore multiple sizes. - // We return the largest size found (image-size default is the first size found) - if (dimensions.images) { - dimensions.width = _.maxBy(dimensions.images, function (w) {return w.width;}).width; - dimensions.height = _.maxBy(dimensions.images, function (h) {return h.height;}).height; - } - - element.attribs.width = dimensions.width; - element.attribs.height = dimensions.height; - - return getLayoutAttribute(element); - } catch (err) { - // revert this element, do not show - element.name = 'img'; - return enter(); + return enter(); } - }).catch(function (err) { - // revert this element, do not show - element.name = 'img'; - return enter(); - }); - } - if ((element.name === 'img' || element.name === 'iframe') && !element.attribs.src) { - return enter(); - } - - if (element.name === 'img' && amperize.config['amp-img']) { - // when we have a gif it should be . - element.name = element.attribs.src.match(/(\.gif$)/) ? 'amp-anim' : 'amp-img'; + /** + * Get the image sizes (width and heigth plus type of image) + * + * https://github.com/image-size/image-size + * + * @param {Object} element + * @return {Object} element incl. width and height + */ + function getImageSize(element) { + var imageObj = url.parse(element.attribs.src), + requestOptions, + timeout = 3000; + + if (!validator.isURL(imageObj.href)) { + // revert this element, do not show + element.name = 'img'; + + return enter(); + } + + // We need the user-agent, otherwise some https request may fail (e. g. cloudfare) + requestOptions = { + headers: { + 'User-Agent': 'Mozilla/5.0' + }, + timeout: timeout, + encoding: null + }; + + return got( + imageObj.href, + requestOptions + ).then(function (response) { + try { + // Using the Buffer rather than an URL requires to use sizeOf synchronously. + // See https://github.com/image-size/image-size#asynchronous + var dimensions = sizeOf(response.body); + + // CASE: `.ico` files might have multiple images and therefore multiple sizes. + // We return the largest size found (image-size default is the first size found) + if (dimensions.images) { + dimensions.width = _.maxBy(dimensions.images, function (w) {return w.width;}).width; + dimensions.height = _.maxBy(dimensions.images, function (h) {return h.height;}).height; + } + + element.attribs.width = dimensions.width; + element.attribs.height = dimensions.height; + + return getLayoutAttribute(element); + } catch (err) { + // revert this element, do not show + element.name = 'img'; + return enter(); + } + }).catch(function () { + // revert this element, do not show + element.name = 'img'; + return enter(); + }); + } - if (!element.attribs.width || !element.attribs.height || !element.attribs.layout) { - if (element.attribs.src.indexOf('http') === 0) { - return getImageSize(element); + if ((element.name === 'img' || element.name === 'iframe') && !element.attribs.src) { + return enter(); } - } - // Fallback to default values for a local image - element.attribs.width = amperize.config['amp-img'].width; - element.attribs.height = amperize.config['amp-img'].height; - return getLayoutAttribute(element); - } - if (element.name ==='iframe') { - element.name = 'amp-iframe'; + if (element.name === 'img' && self.config['amp-img']) { + // when we have a gif it should be . + element.name = element.attribs.src.match(/(\.gif$)/) ? 'amp-anim' : 'amp-img'; + + if (!element.attribs.width || !element.attribs.height || !element.attribs.layout) { + if (element.attribs.src.indexOf('http') === 0) { + return getImageSize(element); + } + } + // Fallback to default values for a local image + element.attribs.width = self.config['amp-img'].width; + element.attribs.height = self.config['amp-img'].height; + return getLayoutAttribute(element); + } - if (!element.attribs.width || !element.attribs.height || !element.attribs.layout) { + if (element.name === 'iframe') { + element.name = 'amp-iframe'; - element.attribs.width = !element.attribs.width ? amperize.config['amp-iframe'].width : element.attribs.width; - element.attribs.height = !element.attribs.height ? amperize.config['amp-iframe'].height : element.attribs.height; - element.attribs.sandbox = !element.attribs.sandbox ? amperize.config['amp-iframe'].sandbox : element.attribs.sandbox; + if (!element.attribs.width || !element.attribs.height || !element.attribs.layout) { + element.attribs.width = !element.attribs.width ? self.config['amp-iframe'].width : element.attribs.width; + element.attribs.height = !element.attribs.height ? self.config['amp-iframe'].height : element.attribs.height; + element.attribs.sandbox = !element.attribs.sandbox ? self.config['amp-iframe'].sandbox : element.attribs.sandbox; - useSecureSchema(element); + useSecureSchema(element); - return getLayoutAttribute(element); - } - } + return getLayoutAttribute(element); + } + } - if (element.name === 'audio') { - element.name = 'amp-audio'; - } + if (element.name === 'audio') { + element.name = 'amp-audio'; + } - useSecureSchema(element); + useSecureSchema(element); - return enter(); - }, done); + return enter(); + }, done); }; module.exports = Amperize; diff --git a/lib/helpers.js b/lib/helpers.js index 0277b5b..bd2e064 100644 --- a/lib/helpers.js +++ b/lib/helpers.js @@ -1,44 +1,42 @@ 'use strict'; -var node = [ - 'tag', 'script', 'style' -]; - -var singular = [ - 'area', 'base', 'br', 'col', 'command', 'embed', 'hr', - 'img', 'input', 'link', 'meta', 'param', 'source', 'wbr', - 'track' -]; +var node = ['tag', 'script', 'style'], + singular = [ + 'area', 'base', 'br', 'col', 'command', 'embed', 'hr', + 'img', 'input', 'link', 'meta', 'param', 'source', 'wbr', + 'track' + ]; function attributes(element) { - var attr = element.attribs - , name = element.name; + var attr = element.attribs; - if (!attr || typeof attr !== 'object') return ''; + if (!attr || typeof attr !== 'object') { + return ''; + } - return Object.keys(attr).reduce(function (result, key) { - return result + ' ' + key + '="' + attr[key] + '"'; - }, ''); + return Object.keys(attr).reduce(function (result, key) { + return result + ' ' + key + '="' + attr[key] + '"'; + }, ''); } exports.tag = exports.script = exports.style = function tag(element) { - return '<' + element.name + attributes(element) + '>'; + return '<' + element.name + attributes(element) + '>'; }; exports.text = function text(element) { - return element.data; + return element.data; }; exports.comment = function comment(element) { - return ''; + return ''; }; exports.directive = function directive(element) { - return '<' + element.data + '>'; -} + return '<' + element.data + '>'; +}; exports.close = function close(element) { - return ~node.indexOf(element.type) && !~singular.indexOf(element.name) - ? '' - : ''; + return ~node.indexOf(element.type) && !~singular.indexOf(element.name) + ? '' + : ''; }; diff --git a/test/.eslintrc.json b/test/.eslintrc.json new file mode 100644 index 0000000..3e40453 --- /dev/null +++ b/test/.eslintrc.json @@ -0,0 +1,238 @@ +{ + "env": { + "es6": true, + "node": true, + "mocha": true + }, + "extends": "eslint:recommended", + "rules": { + "camelcase": "off", + "dot-notation": "off", + "eol-last": "error", + "eqeqeq": "error", + "for-direction": "error", + "func-call-spacing": "error", + "func-name-matching": "off", + "func-names": "off", + "func-style": "off", + "function-paren-newline": "off", + "generator-star-spacing": "error", + "getter-return": "error", + "global-require": "off", + "guard-for-in": "error", + "handle-callback-err": "error", + "id-blacklist": "error", + "id-length": "off", + "id-match": "error", + "indent": "off", + "indent-legacy": "off", + "init-declarations": "off", + "jsx-quotes": "error", + "key-spacing": "off", + "keyword-spacing": "error", + "line-comment-position": "off", + "linebreak-style": [ + "error", + "unix" + ], + "lines-around-comment": "off", + "lines-around-directive": "off", + "lines-between-class-members": [ + "error", + "always" + ], + "max-depth": "error", + "max-len": "off", + "max-lines": "off", + "max-nested-callbacks": "error", + "max-params": "off", + "max-statements": "off", + "max-statements-per-line": "off", + "multiline-comment-style": "off", + "multiline-ternary": "off", + "new-parens": "error", + "newline-after-var": "off", + "newline-before-return": "off", + "newline-per-chained-call": "off", + "no-alert": "error", + "no-array-constructor": "error", + "no-await-in-loop": "error", + "no-bitwise": "off", + "no-buffer-constructor": "off", + "no-caller": "error", + "no-catch-shadow": "error", + "no-confusing-arrow": "error", + "no-console": "off", + "no-continue": "error", + "no-div-regex": "off", + "no-duplicate-imports": "error", + "no-else-return": "off", + "no-empty-function": "off", + "no-eq-null": "error", + "no-eval": "error", + "no-extend-native": "error", + "no-extra-bind": "error", + "no-extra-label": "error", + "no-extra-parens": "off", + "no-floating-decimal": "error", + "no-implicit-globals": "error", + "no-implied-eval": "error", + "no-inline-comments": "off", + "no-inner-declarations": [ + "error", + "functions" + ], + "no-invalid-this": "error", + "no-iterator": "error", + "no-label-var": "error", + "no-labels": "error", + "no-lone-blocks": "error", + "no-lonely-if": "off", + "no-loop-func": "error", + "no-magic-numbers": "off", + "no-mixed-operators": "off", + "no-mixed-requires": "off", + "no-multi-assign": "off", + "no-multi-spaces": "off", + "no-multi-str": "error", + "no-multiple-empty-lines": ["error", {"max": 1}], + "no-native-reassign": "error", + "no-negated-condition": "off", + "no-negated-in-lhs": "error", + "no-nested-ternary": "off", + "no-new": "error", + "no-new-func": "error", + "no-new-object": "error", + "no-new-require": "error", + "no-new-wrappers": "error", + "no-octal-escape": "error", + "no-param-reassign": "off", + "no-path-concat": "off", + "no-plusplus": "error", + "no-process-env": "off", + "no-process-exit": "error", + "no-proto": "error", + "no-prototype-builtins": "off", + "no-regex-spaces": "off", + "no-restricted-globals": "error", + "no-restricted-imports": "error", + "no-restricted-modules": "error", + "no-restricted-properties": "error", + "no-restricted-syntax": "error", + "no-return-assign": "error", + "no-return-await": "error", + "no-script-url": "off", + "no-self-compare": "error", + "no-sequences": "error", + "no-shadow": "off", + "no-shadow-restricted-names": "error", + "no-spaced-func": "error", + "no-sync": "off", + "no-tabs": "error", + "no-template-curly-in-string": "error", + "no-ternary": "off", + "no-throw-literal": "error", + "no-trailing-spaces": "error", + "no-undef-init": "error", + "no-undefined": "off", + "no-underscore-dangle": "off", + "no-unmodified-loop-condition": "error", + "no-unneeded-ternary": "off", + "no-unused-vars": "off", + "no-use-before-define": "off", + "no-useless-call": "error", + "no-useless-computed-key": "error", + "no-useless-concat": "off", + "no-useless-constructor": "error", + "no-useless-escape": "off", + "no-useless-rename": "error", + "no-useless-return": "error", + "no-var": "off", + "no-void": "error", + "no-warning-comments": "off", + "no-whitespace-before-property": "error", + "no-with": "error", + "nonblock-statement-body-position": "error", + "object-curly-newline": [ + "error", + { + "consistent": true + } + ], + "object-curly-spacing": [ + "error", + "never" + ], + "object-property-newline": "off", + "object-shorthand": "off", + "one-var": "off", + "one-var-declaration-per-line": "off", + "operator-assignment": "off", + "operator-linebreak": "off", + "padded-blocks": [ + "error", + "never" + ], + "padding-line-between-statements": "error", + "prefer-arrow-callback": "off", + "prefer-const": "off", + "prefer-destructuring": "off", + "prefer-numeric-literals": "error", + "prefer-promise-reject-errors": "off", + "prefer-reflect": "off", + "prefer-rest-params": "off", + "prefer-spread": "off", + "prefer-template": "off", + "quote-props": [ + "error", + "as-needed" + ], + "quotes": "off", + "radix": "off", + "require-await": "error", + "require-jsdoc": "off", + "rest-spread-spacing": "error", + "semi": ["error", "always"], + "semi-spacing": "error", + "semi-style": [ + "error", + "last" + ], + "sort-imports": "error", + "sort-keys": "off", + "sort-vars": "off", + "space-before-blocks": "error", + "space-before-function-paren": [ + "error", + { + "anonymous": "always", + "named": "never" + } + ], + "space-in-parens": [ + "error", + "never" + ], + "space-infix-ops": "error", + "space-unary-ops": "error", + "spaced-comment": "off", + "strict": "off", + "switch-colon-spacing": "error", + "symbol-description": "error", + "template-curly-spacing": [ + "error", + "never" + ], + "template-tag-spacing": "error", + "unicode-bom": [ + "error", + "never" + ], + "valid-jsdoc": "off", + "vars-on-top": "off", + "wrap-iife": "off", + "wrap-regex": "off", + "yield-star-spacing": "error", + "yoda": "error" + } +} diff --git a/test/amperize.test.js b/test/amperize.test.js index 80187d0..32c861f 100644 --- a/test/amperize.test.js +++ b/test/amperize.test.js @@ -1,486 +1,483 @@ -'use strict'; - -var chai = require('chai') - , expect = chai.expect - , sinon = require('sinon') - , sinonChai = require('sinon-chai') - , nock = require('nock') - , rewire = require('rewire') - , Amperize = rewire('../lib/amperize') - , amperize; +var chai = require('chai'), + expect = chai.expect, + sinon = require('sinon'), + sinonChai = require('sinon-chai'), + nock = require('nock'), + rewire = require('rewire'), + Amperize = rewire('../lib/amperize'), + amperize; chai.use(sinonChai); chai.config.includeStack = true; describe('Amperize', function () { - beforeEach(function () { - amperize = new Amperize(); - }); - - afterEach(function () { - amperize = void 0; - }); - - describe('is a module', function () { - it('which has a constructor', function () { - expect(Amperize).to.be.a('function'); + beforeEach(function () { + amperize = new Amperize(); }); - it('which has default options', function () { - expect(amperize).to.have.property('config'); - expect(amperize.config).to.be.eql({ - 'amp-img': { - layout: 'responsive', - width: 600, - height: 400, - }, - 'amp-anim': { - layout: 'responsive', - width: 600, - height: 400, - }, - 'amp-iframe': { - layout: 'responsive', - width: 600, - height: 400, - sandbox: 'allow-scripts allow-same-origin' - } - }); + afterEach(function () { + amperize = undefined; }); - it('which can be configured', function () { - var configurable = new Amperize({some: 'options'}); - expect(configurable).to.have.property('config'); - expect(configurable.config.some).to.be.equal('options'); - }); + describe('is a module', function () { + it('which has a constructor', function () { + expect(Amperize).to.be.a('function'); + }); - it('which has htmlParser', function () { - expect(amperize).to.have.property('htmlParser'); - expect(amperize.htmlParser).to.be.a('object'); - }); + it('which has default options', function () { + expect(amperize).to.have.property('config'); + expect(amperize.config).to.be.eql({ + 'amp-img': { + layout: 'responsive', + width: 600, + height: 400 + }, + 'amp-anim': { + layout: 'responsive', + width: 600, + height: 400 + }, + 'amp-iframe': { + layout: 'responsive', + width: 600, + height: 400, + sandbox: 'allow-scripts allow-same-origin' + } + }); + }); - it('which has #parse', function () { - expect(amperize).to.have.property('parse'); - expect(amperize.parse).to.be.a('function'); - }); + it('which can be configured', function () { + var configurable = new Amperize({some: 'options'}); + expect(configurable).to.have.property('config'); + expect(configurable.config.some).to.be.equal('options'); + }); - it('which has #amperizer', function () { - expect(amperize).to.have.property('amperizer'); - expect(amperize.amperizer).to.be.a('function'); - }); - }); + it('which has htmlParser', function () { + expect(amperize).to.have.property('htmlParser'); + expect(amperize.htmlParser).to.be.a('object'); + }); - describe('#parse', function () { - var sizeOfMock, - sizeOfStub; + it('which has #parse', function () { + expect(amperize).to.have.property('parse'); + expect(amperize.parse).to.be.a('function'); + }); - beforeEach(function () { - // stubbing the `image-size` lib, so we don't to a request everytime - sizeOfStub = sinon.stub(); + it('which has #amperizer', function () { + expect(amperize).to.have.property('amperizer'); + expect(amperize.amperizer).to.be.a('function'); + }); }); - afterEach(function () { - sinon.restore(); - }); + describe('#parse', function () { + var sizeOfMock, + sizeOfStub; - it('throws an error if no callback provided', function () { - function err() { - amperize.parse('', null); - } + beforeEach(function () { + // stubbing the `image-size` lib, so we don't to a request everytime + sizeOfStub = sinon.stub(); + }); - expect(err).throws('No callback provided'); - }); + afterEach(function () { + sinon.restore(); + }); - it('transforms small into with full image dimensions and fixed layout', function (done) { - sizeOfMock = nock('http://static.wixstatic.com') - .get('/media/355241_d31358572a2542c5a44738ddcb59e7ea.jpg_256') - .reply(200, { - body: '' - }); + it('throws an error if no callback provided', function () { + function err() { + amperize.parse('', null); + } - sizeOfStub.returns({width: 50, height: 50, type: 'jpg'}); - Amperize.__set__('sizeOf', sizeOfStub); - - amperize.parse('', function (error, result) { - expect(result).to.exist; - expect(result).to.contain(''); - done(); - }); - }); + expect(err).throws('No callback provided'); + }); - it('transforms big into with full image dimensions and responsive layout', function (done) { - sizeOfMock = nock('http://static.wixstatic.com') - .get('/media/355241_d31358572a2542c5a44738ddcb59e7ea.jpg_256') - .reply(200, { - body: '' + it('transforms small into with full image dimensions and fixed layout', function (done) { + sizeOfMock = nock('http://static.wixstatic.com') + .get('/media/355241_d31358572a2542c5a44738ddcb59e7ea.jpg_256') + .reply(200, { + body: '' + }); + + sizeOfStub.returns({width: 50, height: 50, type: 'jpg'}); + Amperize.__set__('sizeOf', sizeOfStub); + + amperize.parse('', function (error, result) { + expect(result).to.exist; + expect(result).to.contain(''); + done(); }); + }); - sizeOfStub.returns({width: 350, height: 200, type: 'jpg'}); - Amperize.__set__('sizeOf', sizeOfStub); - - amperize.parse('', function (error, result) { - expect(result).to.exist; - expect(result).to.contain(''); - done(); - }); - }); - - it('transforms into when width and height is set and overwrites it', function (done) { - sizeOfMock = nock('http://somestockwebsite.com') - .get('/image.jpg') - .reply(200, { - body: '' + it('transforms big into with full image dimensions and responsive layout', function (done) { + sizeOfMock = nock('http://static.wixstatic.com') + .get('/media/355241_d31358572a2542c5a44738ddcb59e7ea.jpg_256') + .reply(200, { + body: '' + }); + + sizeOfStub.returns({width: 350, height: 200, type: 'jpg'}); + Amperize.__set__('sizeOf', sizeOfStub); + + amperize.parse('', function (error, result) { + expect(result).to.exist; + expect(result).to.contain(''); + done(); }); + }); - sizeOfStub.returns({width: 350, height: 200, type: 'jpg'}); - Amperize.__set__('sizeOf', sizeOfStub); - - amperize.parse('', function (error, result) { - expect(result).to.exist; - expect(result).to.contain(''); - done(); - }); - }); - - it('transforms into does not overwrite layout attribute', function (done) { - sizeOfMock = nock('http://somestockwebsite.com') - .get('/image.jpg') - .reply(200, { - body: '' + it('transforms into when width and height is set and overwrites it', function (done) { + sizeOfMock = nock('http://somestockwebsite.com') + .get('/image.jpg') + .reply(200, { + body: '' + }); + + sizeOfStub.returns({width: 350, height: 200, type: 'jpg'}); + Amperize.__set__('sizeOf', sizeOfStub); + + amperize.parse('', function (error, result) { + expect(result).to.exist; + expect(result).to.contain(''); + done(); }); - - sizeOfStub.returns({width: 350, height: 200, type: 'jpg'}); - Amperize.__set__('sizeOf', sizeOfStub); - - amperize.parse('', function (error, result) { - expect(result).to.exist; - expect(result).to.contain(''); - done(); - }); - }); - - it('returns largest image value for .ico files', function (done) { - sizeOfMock = nock('https://somewebsite.com') - .get('/favicon.ico') - .reply(200, { - body: '' - }); - - sizeOfStub.returns({ - width: 32, - height: 32, - type: 'ico', - images: [ - {width: 48, height: 48}, - {width: 32, height: 32}, - {width: 16, height: 16} - ] - }); - Amperize.__set__('sizeOf', sizeOfStub); - - amperize.parse('', function (error, result) { - expect(result).to.exist; - expect(result).to.contain(''); - done(); }); - }); - - it('transforms .gif with only height property into with full dimensions by overriding them', function (done) { - sizeOfMock = nock('https://media.giphy.com') - .get('/media/l46CtzgjhTm29Cbjq/giphy.gif') - .reply(200, { - body: '' + it('transforms into does not overwrite layout attribute', function (done) { + sizeOfMock = nock('http://somestockwebsite.com') + .get('/image.jpg') + .reply(200, { + body: '' + }); + + sizeOfStub.returns({width: 350, height: 200, type: 'jpg'}); + Amperize.__set__('sizeOf', sizeOfStub); + + amperize.parse('', function (error, result) { + expect(result).to.exist; + expect(result).to.contain(''); + done(); }); + }); - sizeOfStub.returns({width: 800, height: 600, type: 'gif'}); - Amperize.__set__('sizeOf', sizeOfStub); - - amperize.parse('', function (error, result) { - expect(result).to.exist; - expect(result).to.contain(''); - done(); - }); - }); - - it('transforms ', function (error, result) { - expect(result).to.exist; - expect(result).to.contain(''); - expect(result).to.contain('sandbox="allow-scripts allow-same-origin"') - done(); - }); - }); - - it('transforms ', function (error, result) { - expect(result).to.exist; - expect(result).to.contain(''); - expect(result).to.contain('sandbox="allow-scripts allow-same-origin"') - done(); - }); - }); - - it('transforms ', function (error, result) { - expect(result).to.exist; - expect(result).to.contain(''); - expect(result).to.contain('sandbox="allow-scripts"') - done(); - }); - }); - - it('adds \'https\' protocol to '; - amperize.parse(url, function (error, result) { - expect(result).to.exist; - expect(result).to.contain(''); - expect(result).to.contain('sandbox="allow-scripts allow-same-origin"') - done(); - }); - }); + it('returns largest image value for .ico files', function (done) { + sizeOfMock = nock('https://somewebsite.com') + .get('/favicon.ico') + .reply(200, { + body: '' + }); + + sizeOfStub.returns({ + width: 32, + height: 32, + type: 'ico', + images: [ + {width: 48, height: 48}, + {width: 32, height: 32}, + {width: 16, height: 16} + ] + }); + Amperize.__set__('sizeOf', sizeOfStub); + + amperize.parse('', function (error, result) { + expect(result).to.exist; + expect(result).to.contain(''); + done(); + }); + }); - it('adds \'https\' protocol to

via GIPHY

'; - amperize.parse(url, function (error, result) { - expect(result).to.exist; - expect(result).to.contain(''); - expect(result).to.contain('sandbox="allow-scripts allow-same-origin"') - done(); - }); - }); + it('transforms .gif with only height property into with full dimensions by overriding them', function (done) { + sizeOfMock = nock('https://media.giphy.com') + .get('/media/l46CtzgjhTm29Cbjq/giphy.gif') + .reply(200, { + body: '' + }); + + sizeOfStub.returns({width: 800, height: 600, type: 'gif'}); + Amperize.__set__('sizeOf', sizeOfStub); + + amperize.parse('', function (error, result) { + expect(result).to.exist; + expect(result).to.contain(''); + done(); + }); + }); - it('transforms local into with default image dimensions', function (done) { - amperize.parse('', function (error, result) { - expect(result).to.exist; - expect(result).to.contain(''); - done(); - }); - }); + it('transforms ', function (error, result) { + expect(result).to.exist; + expect(result).to.contain(''); + expect(result).to.contain('sandbox="allow-scripts allow-same-origin"'); + done(); + }); + }); - it('can handle tag without src and does not transform it', function (done) { - amperize.parse('

some text here

', function (error, result) { - expect(result).to.exist; - expect(result).to.be.equal('

some text here

'); - done(); - }); - }); + it('transforms ', function (error, result) { + expect(result).to.exist; + expect(result).to.contain(''); + expect(result).to.contain('sandbox="allow-scripts allow-same-origin"'); + done(); + }); + }); - it('can handle invalid URLs', function (done) { - amperize.parse('', function (error, result) { - expect(result).to.exist; - expect(result).to.be.equal(''); - done(); - }); - }); + it('transforms ', function (error, result) { + expect(result).to.exist; + expect(result).to.contain(''); + expect(result).to.contain('sandbox="allow-scripts"'); + done(); + }); + }); - it('can handle '); - done(); - }); - }); + it('adds \'https\' protocol to '; + amperize.parse(url, function (error, result) { + expect(result).to.exist; + expect(result).to.contain(''); + expect(result).to.contain('sandbox="allow-scripts allow-same-origin"'); + done(); + }); + }); - it('transforms