From 7ddbb1eedce437dadbf54faebde91cef2e7292ab Mon Sep 17 00:00:00 2001 From: Harminder Virk Date: Fri, 31 Mar 2017 14:27:08 +0530 Subject: [PATCH] feat(globals): add globals --- package.json | 1 + src/Globals/index.js | 240 +++++++++++++++++++++++++++++++++++++- test/unit/globals.spec.js | 61 ++++++++++ 3 files changed, 301 insertions(+), 1 deletion(-) create mode 100644 test/unit/globals.spec.js diff --git a/package.json b/package.json index 17bd8f5..b69e4cb 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ }, "dependencies": { "debug": "^2.6.1", + "encodeurl": "^1.0.1", "escape-html": "^1.0.3", "esprima": "^3.1.3", "indent-string": "^3.1.0", diff --git a/src/Globals/index.js b/src/Globals/index.js index aedd00f..ec4b237 100644 --- a/src/Globals/index.js +++ b/src/Globals/index.js @@ -10,35 +10,263 @@ */ const _ = require('lodash') +const encodeurl = require('encodeurl') +/** + * Returns an array of numbers with in + * the defined range + * + * @method range + * + * @param {Number} [start = 0] + * @param {Number} end + * @param {Number} [step=1] + * + * @return {Array} + */ const range = function (start, end) { return _.range(start, end) } +/** + * Converts an array into batch of multiple + * arrays. + * + * @method batch + * + * @param {Array} input + * @param {Number} size + * + * @return {Array} + * + * @example + * ``` + * [1, 2, 3, 4] + * // returns + * [[1, 2], [3, 4]] + * ``` + */ const batch = function (input, size) { return _.chunk(input, size) } +/** + * Convert an object to JSON string via + * JSON.stringify + * + * @method toJSON + * + * @param {Object} input + * @param {Number} indent + * + * @return {String} + */ const toJSON = function (input, indent = 2) { return JSON.stringify(input, null, indent) } +/** + * Returns the 1st item from an array + * + * @method first + * + * @param {Array} collection + * + * @return {Mixed} + */ const first = function (collection) { return _.first(collection) } +/** + * Returns the last item from an array + * + * @method last + * + * @param {Array} collection + * + * @return {Mixed} + */ const last = function (collection) { return _.last(collection) } +/** + * Groupby a collection with some field name + * + * @method groupBy + * + * @param {Array} collection + * @param {String|Number|Function} field + * + * @return {Array} + */ const groupBy = function (collection, field) { return _.groupBy(collection, field) } +/** + * Returns the size of an element. Parsers + * arrays and strings + * + * @method size + * + * @param {Array|String} input + * + * @return {Number} + */ const size = function (input) { return _.size(input) } +/** + * Returns an element by replacing dynamic values + * inside it. It is very simple to print an + * HTML string inside shorthand if statemnt. + * + * @method el + * + * @param {String} htmlStr + * @param {Object} hash + * + * @return {Object} - Instance of safe string + * + * @example + * ``` + * this.el(' $title ', { title: 'Docs', url: '/docs' }) + * // returns + * // ' Docs ' + * ``` + */ +const el = function (htmlStr, hash) { + return this.safe(htmlStr.replace(/\$([\w.-]+)/g, (match, group) => { + return _.get(hash, _.toPath(group)) + })) +} + +/** + * Convert a string to camelcase + * + * @method camelCase + * + * @param {String} input + * + * @return {String} + */ +const camelCase = function (input) { + return _.camelCase(input) +} + +/** + * Capitalize a string. + * + * @method upperCase + * + * @param {String} input + * + * @return {String} + */ +const upperCase = function (input) { + return _.upperCase(input) +} + +/** + * Lowercase a string. + * + * @method lowerCase + * + * @param {String} input + * + * @return {String} + */ +const lowerCase = function (input) { + return _.lowerCase(input) +} + +/** + * Lowercase the first character in string. + * + * @method lowerFirst + * + * @param {String} input + * + * @return {String} + */ +const lowerFirst = function (input) { + return _.lowerFirst(input) +} + +/** + * Upercase the first character in string. + * + * @method upperFirst + * + * @param {String} input + * + * @return {String} + */ +const upperFirst = function (input) { + return _.upperFirst(input) +} + +/** + * Capitalize each first word of a string + * + * @method capitalize + * + * @param {String} input + * + * @return {String} + */ +const capitalize = function (input) { + return _.startCase(input) +} + +/** + * Truncate a string to given number to characters + * + * @method truncate + * + * @param {String} input + * @param {Number} limitTo + * @param {String} [omission = ...] + * + * @return {String} + */ +const truncate = function (input, limitTo, omission) { + return _.truncate(input, { + length: limitTo, + omission: omission + }) +} + +/** + * Converts a plain url to an anchor tag + * + * @method toAnchor + * + * @param {String} url + * @param {Sting} title + * + * @return {Object} - Instance of safe object + */ +const toAnchor = function (url, title = url) { + return this.safe(` ${title} `) +} + +/** + * Encodes a url + * + * @method urlEncode + * + * @param {String} url + * + * @return {String} + */ +const urlEncode = function (url) { + return encodeurl(url) +} + module.exports = { range, batch, @@ -46,5 +274,15 @@ module.exports = { first, last, groupBy, - size + size, + el, + camelCase, + upperCase, + upperFirst, + lowerCase, + lowerFirst, + capitalize, + truncate, + toAnchor, + urlEncode } diff --git a/test/unit/globals.spec.js b/test/unit/globals.spec.js new file mode 100644 index 0000000..55f71e1 --- /dev/null +++ b/test/unit/globals.spec.js @@ -0,0 +1,61 @@ +'use strict' + +const test = require('japa') +const Globals = require('../../src/Globals') + +test.group('Globals', () => { + test('return safe element object when .el global is called', (assert) => { + const context = { + safe (input) { + return input + } + } + const output = Globals.el.bind(context)(' $title ', { title: 'Docs', url: '/docs' }) + assert.equal(output, ' Docs ') + }) + + test('replace with nested objects', (assert) => { + const context = { + safe (input) { + return input + } + } + const output = Globals.el.bind(context)(' $meta.title ', { meta: {title: 'Docs', url: '/docs'} }) + assert.equal(output, ' Docs ') + }) + + test('replace with nested objects inside an array', (assert) => { + const context = { + safe (input) { + return input + } + } + const output = Globals.el.bind(context)(' $meta.0.title ', { meta: [{title: 'Docs', url: '/docs'}] }) + assert.equal(output, ' Docs ') + }) + + test('convert a link to an anchor tag', (assert) => { + const context = { + safe (input) { + return input + } + } + const output = Globals.toAnchor.bind(context)('http://google.com') + assert.equal(output, ' http://google.com ') + }) + + test('convert a link to an anchor tag with custom title', (assert) => { + const context = { + safe (input) { + return input + } + } + const output = Globals.toAnchor.bind(context)('http://google.com', 'Google') + assert.equal(output, ' Google ') + }) + + test('encode url', (assert) => { + const output = Globals.urlEncode('http://foo.com?username=aman virk') + assert.equal(output, 'http://foo.com?username=aman%20virk') + }) +})