[Pkg-javascript-commits] [node-cliui] 01/03: Import Upstream version 3.2.0
Paolo Greppi
paolog-guest at moszumanska.debian.org
Sat Nov 26 00:35:41 UTC 2016
This is an automated email from the git hooks/post-receive script.
paolog-guest pushed a commit to branch master
in repository node-cliui.
commit d69c9cedee7652d67954b44137535eb71b144696
Author: Paolo Greppi <paolo.greppi at libpf.com>
Date: Sat Nov 26 00:25:41 2016 +0000
Import Upstream version 3.2.0
---
.coveralls.yml | 1 +
.gitignore | 3 +
.travis.yml | 7 +
CHANGELOG.md | 15 ++
LICENSE.txt | 14 ++
README.md | 110 ++++++++++++++
index.js | 316 +++++++++++++++++++++++++++++++++++++++
package.json | 64 ++++++++
screenshot.png | Bin 0 -> 18253 bytes
test/cliui.js | 457 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
10 files changed, 987 insertions(+)
diff --git a/.coveralls.yml b/.coveralls.yml
new file mode 100644
index 0000000..73367db
--- /dev/null
+++ b/.coveralls.yml
@@ -0,0 +1 @@
+repo_token: NiRhyj91Z2vtgob6XdEAqs83rzNnbMZUu
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..62adae5
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+.DS_Store
+node_modules
+.nyc_output
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..ea02669
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,7 @@
+language: node_js
+node_js:
+ - "0.10"
+ - "0.12"
+ - "4"
+ - "5"
+after_script: npm run coverage
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..ef6a35e
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,15 @@
+# Change Log
+
+All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
+
+<a name="3.2.0"></a>
+# [3.2.0](https://github.com/yargs/cliui/compare/v3.1.2...v3.2.0) (2016-04-11)
+
+
+### Bug Fixes
+
+* reduces tarball size ([acc6c33](https://github.com/yargs/cliui/commit/acc6c33))
+
+### Features
+
+* adds standard-version for release management ([ff84e32](https://github.com/yargs/cliui/commit/ff84e32))
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000..c7e2747
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,14 @@
+Copyright (c) 2015, Contributors
+
+Permission to use, copy, modify, and/or distribute this software
+for any purpose with or without fee is hereby granted, provided
+that the above copyright notice and this permission notice
+appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE
+LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
+OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..028392c
--- /dev/null
+++ b/README.md
@@ -0,0 +1,110 @@
+# cliui
+
+[![Build Status](https://travis-ci.org/yargs/cliui.svg)](https://travis-ci.org/yargs/cliui)
+[![Coverage Status](https://coveralls.io/repos/yargs/cliui/badge.svg?branch=)](https://coveralls.io/r/yargs/cliui?branch=)
+[![NPM version](https://img.shields.io/npm/v/cliui.svg)](https://www.npmjs.com/package/cliui)
+[![Standard Version](https://img.shields.io/badge/release-standard%20version-brightgreen.svg)](https://github.com/conventional-changelog/standard-version)
+
+easily create complex multi-column command-line-interfaces.
+
+## Example
+
+```js
+var ui = require('cliui')({
+ width: 80
+})
+
+ui.div('Usage: $0 [command] [options]')
+
+ui.div({
+ text: 'Options:',
+ padding: [2, 0, 2, 0]
+})
+
+ui.div(
+ {
+ text: "-f, --file",
+ width: 20,
+ padding: [0, 4, 0, 4]
+ },
+ {
+ text: "the file to load." +
+ chalk.green("(if this description is long it wraps).")
+ ,
+ width: 20
+ },
+ {
+ text: chalk.red("[required]"),
+ align: 'right'
+ }
+)
+
+console.log(ui.toString())
+```
+
+<img width="500" src="screenshot.png">
+
+## Layout DSL
+
+cliui exposes a simple layout DSL:
+
+If you create a single `ui.row`, passing a string rather than an
+object:
+
+* `\n`: characters will be interpreted as new rows.
+* `\t`: characters will be interpreted as new columns.
+* `\s`: characters will be interpreted as padding.
+
+**as an example...**
+
+```js
+var ui = require('./')({
+ width: 60
+})
+
+ui.div(
+ 'Usage: node ./bin/foo.js\n' +
+ ' <regex>\t provide a regex\n' +
+ ' <glob>\t provide a glob\t [required]'
+)
+
+console.log(ui.toString())
+```
+
+**will output:**
+
+```shell
+Usage: node ./bin/foo.js
+ <regex> provide a regex
+ <glob> provide a glob [required]
+```
+
+## Methods
+
+```js
+cliui = require('cliui')
+```
+
+### cliui({width: integer})
+
+Specify the maximum width of the UI being generated.
+
+### cliui({wrap: boolean})
+
+Enable or disable the wrapping of text in a column.
+
+### cliui.div(column, column, column)
+
+Create a row with any number of columns, a column
+can either be a string, or an object with the following
+options:
+
+* **width:** the width of a column.
+* **align:** alignment, `right` or `center`.
+* **padding:** `[top, right, bottom, left]`.
+* **border:** should a border be placed around the div?
+
+### cliui.span(column, column, column)
+
+Similar to `div`, except the next row will be appended without
+a new line being created.
diff --git a/index.js b/index.js
new file mode 100644
index 0000000..e501e78
--- /dev/null
+++ b/index.js
@@ -0,0 +1,316 @@
+var stringWidth = require('string-width')
+var stripAnsi = require('strip-ansi')
+var wrap = require('wrap-ansi')
+var align = {
+ right: alignRight,
+ center: alignCenter
+}
+var top = 0
+var right = 1
+var bottom = 2
+var left = 3
+
+function UI (opts) {
+ this.width = opts.width
+ this.wrap = opts.wrap
+ this.rows = []
+}
+
+UI.prototype.span = function () {
+ var cols = this.div.apply(this, arguments)
+ cols.span = true
+}
+
+UI.prototype.div = function () {
+ if (arguments.length === 0) this.div('')
+ if (this.wrap && this._shouldApplyLayoutDSL.apply(this, arguments)) {
+ return this._applyLayoutDSL(arguments[0])
+ }
+
+ var cols = []
+
+ for (var i = 0, arg; (arg = arguments[i]) !== undefined; i++) {
+ if (typeof arg === 'string') cols.push(this._colFromString(arg))
+ else cols.push(arg)
+ }
+
+ this.rows.push(cols)
+ return cols
+}
+
+UI.prototype._shouldApplyLayoutDSL = function () {
+ return arguments.length === 1 && typeof arguments[0] === 'string' &&
+ /[\t\n]/.test(arguments[0])
+}
+
+UI.prototype._applyLayoutDSL = function (str) {
+ var _this = this
+ var rows = str.split('\n')
+ var leftColumnWidth = 0
+
+ // simple heuristic for layout, make sure the
+ // second column lines up along the left-hand.
+ // don't allow the first column to take up more
+ // than 50% of the screen.
+ rows.forEach(function (row) {
+ var columns = row.split('\t')
+ if (columns.length > 1 && stringWidth(columns[0]) > leftColumnWidth) {
+ leftColumnWidth = Math.min(
+ Math.floor(_this.width * 0.5),
+ stringWidth(columns[0])
+ )
+ }
+ })
+
+ // generate a table:
+ // replacing ' ' with padding calculations.
+ // using the algorithmically generated width.
+ rows.forEach(function (row) {
+ var columns = row.split('\t')
+ _this.div.apply(_this, columns.map(function (r, i) {
+ return {
+ text: r.trim(),
+ padding: _this._measurePadding(r),
+ width: (i === 0 && columns.length > 1) ? leftColumnWidth : undefined
+ }
+ }))
+ })
+
+ return this.rows[this.rows.length - 1]
+}
+
+UI.prototype._colFromString = function (str) {
+ return {
+ text: str,
+ padding: this._measurePadding(str)
+ }
+}
+
+UI.prototype._measurePadding = function (str) {
+ // measure padding without ansi escape codes
+ var noAnsi = stripAnsi(str)
+ return [0, noAnsi.match(/\s*$/)[0].length, 0, noAnsi.match(/^\s*/)[0].length]
+}
+
+UI.prototype.toString = function () {
+ var _this = this
+ var lines = []
+
+ _this.rows.forEach(function (row, i) {
+ _this.rowToString(row, lines)
+ })
+
+ // don't display any lines with the
+ // hidden flag set.
+ lines = lines.filter(function (line) {
+ return !line.hidden
+ })
+
+ return lines.map(function (line) {
+ return line.text
+ }).join('\n')
+}
+
+UI.prototype.rowToString = function (row, lines) {
+ var _this = this
+ var padding
+ var rrows = this._rasterize(row)
+ var str = ''
+ var ts
+ var width
+ var wrapWidth
+
+ rrows.forEach(function (rrow, r) {
+ str = ''
+ rrow.forEach(function (col, c) {
+ ts = '' // temporary string used during alignment/padding.
+ width = row[c].width // the width with padding.
+ wrapWidth = _this._negatePadding(row[c]) // the width without padding.
+
+ ts += col
+
+ for (var i = 0; i < wrapWidth - stringWidth(col); i++) {
+ ts += ' '
+ }
+
+ // align the string within its column.
+ if (row[c].align && row[c].align !== 'left' && _this.wrap) {
+ ts = align[row[c].align](ts, wrapWidth)
+ if (stringWidth(ts) < wrapWidth) ts += new Array(width - stringWidth(ts)).join(' ')
+ }
+
+ // apply border and padding to string.
+ padding = row[c].padding || [0, 0, 0, 0]
+ if (padding[left]) str += new Array(padding[left] + 1).join(' ')
+ str += addBorder(row[c], ts, '| ')
+ str += ts
+ str += addBorder(row[c], ts, ' |')
+ if (padding[right]) str += new Array(padding[right] + 1).join(' ')
+
+ // if prior row is span, try to render the
+ // current row on the prior line.
+ if (r === 0 && lines.length > 0) {
+ str = _this._renderInline(str, lines[lines.length - 1])
+ }
+ })
+
+ // remove trailing whitespace.
+ lines.push({
+ text: str.replace(/ +$/, ''),
+ span: row.span
+ })
+ })
+
+ return lines
+}
+
+function addBorder (col, ts, style) {
+ if (col.border) {
+ if (/[.']-+[.']/.test(ts)) return ''
+ else if (ts.trim().length) return style
+ else return ' '
+ }
+ return ''
+}
+
+// if the full 'source' can render in
+// the target line, do so.
+UI.prototype._renderInline = function (source, previousLine) {
+ var leadingWhitespace = source.match(/^ */)[0].length
+ var target = previousLine.text
+ var targetTextWidth = stringWidth(target.trimRight())
+
+ if (!previousLine.span) return source
+
+ // if we're not applying wrapping logic,
+ // just always append to the span.
+ if (!this.wrap) {
+ previousLine.hidden = true
+ return target + source
+ }
+
+ if (leadingWhitespace < targetTextWidth) return source
+
+ previousLine.hidden = true
+
+ return target.trimRight() + new Array(leadingWhitespace - targetTextWidth + 1).join(' ') + source.trimLeft()
+}
+
+UI.prototype._rasterize = function (row) {
+ var _this = this
+ var i
+ var rrow
+ var rrows = []
+ var widths = this._columnWidths(row)
+ var wrapped
+
+ // word wrap all columns, and create
+ // a data-structure that is easy to rasterize.
+ row.forEach(function (col, c) {
+ // leave room for left and right padding.
+ col.width = widths[c]
+ if (_this.wrap) wrapped = wrap(col.text, _this._negatePadding(col), {hard: true}).split('\n')
+ else wrapped = col.text.split('\n')
+
+ if (col.border) {
+ wrapped.unshift('.' + new Array(_this._negatePadding(col) + 3).join('-') + '.')
+ wrapped.push("'" + new Array(_this._negatePadding(col) + 3).join('-') + "'")
+ }
+
+ // add top and bottom padding.
+ if (col.padding) {
+ for (i = 0; i < (col.padding[top] || 0); i++) wrapped.unshift('')
+ for (i = 0; i < (col.padding[bottom] || 0); i++) wrapped.push('')
+ }
+
+ wrapped.forEach(function (str, r) {
+ if (!rrows[r]) rrows.push([])
+
+ rrow = rrows[r]
+
+ for (var i = 0; i < c; i++) {
+ if (rrow[i] === undefined) rrow.push('')
+ }
+ rrow.push(str)
+ })
+ })
+
+ return rrows
+}
+
+UI.prototype._negatePadding = function (col) {
+ var wrapWidth = col.width
+ if (col.padding) wrapWidth -= (col.padding[left] || 0) + (col.padding[right] || 0)
+ if (col.border) wrapWidth -= 4
+ return wrapWidth
+}
+
+UI.prototype._columnWidths = function (row) {
+ var _this = this
+ var widths = []
+ var unset = row.length
+ var unsetWidth
+ var remainingWidth = this.width
+
+ // column widths can be set in config.
+ row.forEach(function (col, i) {
+ if (col.width) {
+ unset--
+ widths[i] = col.width
+ remainingWidth -= col.width
+ } else {
+ widths[i] = undefined
+ }
+ })
+
+ // any unset widths should be calculated.
+ if (unset) unsetWidth = Math.floor(remainingWidth / unset)
+ widths.forEach(function (w, i) {
+ if (!_this.wrap) widths[i] = row[i].width || stringWidth(row[i].text)
+ else if (w === undefined) widths[i] = Math.max(unsetWidth, _minWidth(row[i]))
+ })
+
+ return widths
+}
+
+// calculates the minimum width of
+// a column, based on padding preferences.
+function _minWidth (col) {
+ var padding = col.padding || []
+ var minWidth = 1 + (padding[left] || 0) + (padding[right] || 0)
+ if (col.border) minWidth += 4
+ return minWidth
+}
+
+function alignRight (str, width) {
+ str = str.trim()
+ var padding = ''
+ var strWidth = stringWidth(str)
+
+ if (strWidth < width) {
+ padding = new Array(width - strWidth + 1).join(' ')
+ }
+
+ return padding + str
+}
+
+function alignCenter (str, width) {
+ str = str.trim()
+ var padding = ''
+ var strWidth = stringWidth(str.trim())
+
+ if (strWidth < width) {
+ padding = new Array(parseInt((width - strWidth) / 2, 10) + 1).join(' ')
+ }
+
+ return padding + str
+}
+
+module.exports = function (opts) {
+ opts = opts || {}
+
+ return new UI({
+ width: (opts || {}).width || 80,
+ wrap: typeof opts.wrap === 'boolean' ? opts.wrap : true
+ })
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..31c654c
--- /dev/null
+++ b/package.json
@@ -0,0 +1,64 @@
+{
+ "name": "cliui",
+ "version": "3.2.0",
+ "description": "easily create complex multi-column command-line-interfaces",
+ "main": "index.js",
+ "scripts": {
+ "pretest": "standard",
+ "test": "nyc mocha",
+ "coverage": "nyc --reporter=text-lcov mocha | coveralls",
+ "version": "standard-version"
+ },
+ "repository": {
+ "type": "git",
+ "url": "http://github.com/yargs/cliui.git"
+ },
+ "config": {
+ "blanket": {
+ "pattern": [
+ "index.js"
+ ],
+ "data-cover-never": [
+ "node_modules",
+ "test"
+ ],
+ "output-reporter": "spec"
+ }
+ },
+ "standard": {
+ "ignore": [
+ "**/example/**"
+ ],
+ "globals": [
+ "it"
+ ]
+ },
+ "keywords": [
+ "cli",
+ "command-line",
+ "layout",
+ "design",
+ "console",
+ "wrap",
+ "table"
+ ],
+ "author": "Ben Coe <ben at npmjs.com>",
+ "license": "ISC",
+ "dependencies": {
+ "string-width": "^1.0.1",
+ "strip-ansi": "^3.0.1",
+ "wrap-ansi": "^2.0.0"
+ },
+ "devDependencies": {
+ "chai": "^3.5.0",
+ "chalk": "^1.1.2",
+ "coveralls": "^2.11.8",
+ "mocha": "^2.4.5",
+ "nyc": "^6.4.0",
+ "standard": "^6.0.8",
+ "standard-version": "^2.1.2"
+ },
+ "files": [
+ "index.js"
+ ]
+}
\ No newline at end of file
diff --git a/screenshot.png b/screenshot.png
new file mode 100644
index 0000000..d969fa0
Binary files /dev/null and b/screenshot.png differ
diff --git a/test/cliui.js b/test/cliui.js
new file mode 100644
index 0000000..fd27f5a
--- /dev/null
+++ b/test/cliui.js
@@ -0,0 +1,457 @@
+/* global describe, it */
+
+require('chai').should()
+
+var chalk = require('chalk')
+var cliui = require('../')
+var stripAnsi = require('strip-ansi')
+
+describe('cliui', function () {
+ describe('div', function () {
+ it("wraps text at 'width' if a single column is given", function () {
+ var ui = cliui({
+ width: 10
+ })
+
+ ui.div('i am a string that should be wrapped')
+
+ ui.toString().split('\n').forEach(function (row) {
+ row.length.should.be.lte(10)
+ })
+ })
+
+ it('evenly divides text across columns if multiple columns are given', function () {
+ var ui = cliui({
+ width: 40
+ })
+
+ ui.div(
+ {text: 'i am a string that should be wrapped', width: 15},
+ 'i am a second string that should be wrapped',
+ 'i am a third string that should be wrapped'
+ )
+
+ // total width of all columns is <=
+ // the width cliui is initialized with.
+ ui.toString().split('\n').forEach(function (row) {
+ row.length.should.be.lte(40)
+ })
+
+ // it should wrap each column appropriately.
+ var expected = [
+ 'i am a string i am a i am a third',
+ 'that should be second string that',
+ 'wrapped string that should be',
+ ' should be wrapped',
+ ' wrapped'
+ ]
+
+ ui.toString().split('\n').should.eql(expected)
+ })
+
+ it('allows for a blank row to be appended', function () {
+ var ui = cliui({
+ width: 40
+ })
+
+ ui.div()
+
+ // it should wrap each column appropriately.
+ var expected = ['']
+
+ ui.toString().split('\n').should.eql(expected)
+ })
+ })
+
+ describe('_columnWidths', function () {
+ it('uses same width for each column by default', function () {
+ var ui = cliui({
+ width: 40
+ })
+ var widths = ui._columnWidths([{}, {}, {}])
+
+ widths[0].should.equal(13)
+ widths[1].should.equal(13)
+ widths[2].should.equal(13)
+ })
+
+ it('divides width over remaining columns if first column has width specified', function () {
+ var ui = cliui({
+ width: 40
+ })
+ var widths = ui._columnWidths([{width: 20}, {}, {}])
+
+ widths[0].should.equal(20)
+ widths[1].should.equal(10)
+ widths[2].should.equal(10)
+ })
+
+ it('divides width over remaining columns if middle column has width specified', function () {
+ var ui = cliui({
+ width: 40
+ })
+ var widths = ui._columnWidths([{}, {width: 10}, {}])
+
+ widths[0].should.equal(15)
+ widths[1].should.equal(10)
+ widths[2].should.equal(15)
+ })
+
+ it('keeps track of remaining width if multiple columns have width specified', function () {
+ var ui = cliui({
+ width: 40
+ })
+ var widths = ui._columnWidths([{width: 20}, {width: 12}, {}])
+
+ widths[0].should.equal(20)
+ widths[1].should.equal(12)
+ widths[2].should.equal(8)
+ })
+
+ it('uses a sane default if impossible widths are specified', function () {
+ var ui = cliui({
+ width: 40
+ })
+ var widths = ui._columnWidths([{width: 30}, {width: 30}, {padding: [0, 2, 0, 1]}])
+
+ widths[0].should.equal(30)
+ widths[1].should.equal(30)
+ widths[2].should.equal(4)
+ })
+ })
+
+ describe('alignment', function () {
+ it('allows a column to be right aligned', function () {
+ var ui = cliui({
+ width: 40
+ })
+
+ ui.div(
+ 'i am a string',
+ {text: 'i am a second string', align: 'right'},
+ 'i am a third string that should be wrapped'
+ )
+
+ // it should right-align the second column.
+ var expected = [
+ 'i am a stringi am a secondi am a third',
+ ' stringstring that',
+ ' should be',
+ ' wrapped'
+ ]
+
+ ui.toString().split('\n').should.eql(expected)
+ })
+
+ it('allows a column to be center aligned', function () {
+ var ui = cliui({
+ width: 60
+ })
+
+ ui.div(
+ 'i am a string',
+ {text: 'i am a second string', align: 'center', padding: [0, 2, 0, 2]},
+ 'i am a third string that should be wrapped'
+ )
+
+ // it should right-align the second column.
+ var expected = [
+ 'i am a string i am a second i am a third string',
+ ' string that should be',
+ ' wrapped'
+ ]
+
+ ui.toString().split('\n').should.eql(expected)
+ })
+ })
+
+ describe('padding', function () {
+ it('handles left/right padding', function () {
+ var ui = cliui({
+ width: 40
+ })
+
+ ui.div(
+ {text: 'i have padding on my left', padding: [0, 0, 0, 4]},
+ {text: 'i have padding on my right', padding: [0, 2, 0, 0], align: 'center'},
+ {text: 'i have no padding', padding: [0, 0, 0, 0]}
+ )
+
+ // it should add left/right padding to columns.
+ var expected = [
+ ' i have i have i have no',
+ ' padding padding on padding',
+ ' on my my right',
+ ' left'
+ ]
+
+ ui.toString().split('\n').should.eql(expected)
+ })
+
+ it('handles top/bottom padding', function () {
+ var ui = cliui({
+ width: 40
+ })
+
+ ui.div(
+ 'i am a string',
+ {text: 'i am a second string', padding: [2, 0, 0, 0]},
+ {text: 'i am a third string that should be wrapped', padding: [0, 0, 1, 0]}
+ )
+
+ // it should add top/bottom padding to second
+ // and third columns.
+ var expected = [
+ 'i am a string i am a third',
+ ' string that',
+ ' i am a secondshould be',
+ ' string wrapped',
+ ''
+ ]
+
+ ui.toString().split('\n').should.eql(expected)
+ })
+
+ it('preserves leading whitespace as padding', function () {
+ var ui = cliui()
+
+ ui.div(' LEADING WHITESPACE')
+ ui.div('\u001b[34m with ansi\u001b[39m')
+
+ var expected = [
+ ' LEADING WHITESPACE',
+ ' with ansi'
+ ]
+
+ ui.toString().split('\n').map(function (l) {
+ return stripAnsi(l)
+ }).should.eql(expected)
+ })
+ })
+
+ describe('border', function () {
+ it('allows a border to be placed around a div', function () {
+ var ui = cliui({
+ width: 40
+ })
+
+ ui.div(
+ {text: 'i am a first string', padding: [0, 0, 0, 0], border: true},
+ {text: 'i am a second string', padding: [1, 0, 0, 0], border: true}
+ )
+
+ var expected = [
+ '.------------------.',
+ '| i am a first |.------------------.',
+ '| string || i am a second |',
+ "'------------------'| string |",
+ " '------------------'"
+ ]
+
+ ui.toString().split('\n').should.eql(expected)
+ })
+ })
+
+ describe('wrap', function () {
+ it('allows wordwrap to be disabled', function () {
+ var ui = cliui({
+ wrap: false
+ })
+
+ ui.div(
+ {text: 'i am a string', padding: [0, 1, 0, 0]},
+ {text: 'i am a second string', padding: [0, 2, 0, 0]},
+ {text: 'i am a third string that should not be wrapped', padding: [0, 0, 0, 2]}
+ )
+
+ ui.toString().should.equal('i am a string i am a second string i am a third string that should not be wrapped')
+ })
+ })
+
+ describe('span', function () {
+ it('appends the next row to the end of the prior row if it fits', function () {
+ var ui = cliui({
+ width: 40
+ })
+
+ ui.span(
+ {text: 'i am a string that will be wrapped', width: 30}
+ )
+
+ ui.div(
+ {text: ' [required] [default: 99]', align: 'right'}
+ )
+
+ var expected = [
+ 'i am a string that will be',
+ 'wrapped [required] [default: 99]'
+ ]
+
+ ui.toString().split('\n').should.eql(expected)
+ })
+
+ it('does not append the string if it does not fit on the prior row', function () {
+ var ui = cliui({
+ width: 40
+ })
+
+ ui.span(
+ {text: 'i am a string that will be wrapped', width: 30}
+ )
+
+ ui.div(
+ {text: 'i am a second row', align: 'left'}
+ )
+
+ var expected = [
+ 'i am a string that will be',
+ 'wrapped',
+ 'i am a second row'
+ ]
+
+ ui.toString().split('\n').should.eql(expected)
+ })
+
+ it('always appends text to prior span if wrap is disabled', function () {
+ var ui = cliui({
+ wrap: false,
+ width: 40
+ })
+
+ ui.span(
+ {text: 'i am a string that will be wrapped', width: 30}
+ )
+
+ ui.div(
+ {text: 'i am a second row', align: 'left', padding: [0, 0, 0, 3]}
+ )
+
+ ui.div('a third line')
+
+ var expected = [
+ 'i am a string that will be wrapped i am a second row',
+ 'a third line'
+ ]
+
+ ui.toString().split('\n').should.eql(expected)
+ })
+
+ it('appends to prior line appropriately when strings contain ansi escape codes', function () {
+ var ui = cliui({
+ width: 40
+ })
+
+ ui.span(
+ {text: chalk.green('i am a string that will be wrapped'), width: 30}
+ )
+
+ ui.div(
+ {text: chalk.blue(' [required] [default: 99]'), align: 'right'}
+ )
+
+ var expected = [
+ 'i am a string that will be',
+ 'wrapped [required] [default: 99]'
+ ]
+
+ ui.toString().split('\n').map(function (l) {
+ return stripAnsi(l)
+ }).should.eql(expected)
+ })
+ })
+
+ describe('layoutDSL', function () {
+ it('turns tab into multiple columns', function () {
+ var ui = cliui({
+ width: 60
+ })
+
+ ui.div(
+ ' <regex> \tmy awesome regex\n <my second thing> \tanother row\t a third column'
+ )
+
+ var expected = [
+ ' <regex> my awesome regex',
+ ' <my second thing> another row a third column'
+ ]
+
+ ui.toString().split('\n').should.eql(expected)
+ })
+
+ it('turns newline into multiple rows', function () {
+ var ui = cliui({
+ width: 40
+ })
+
+ ui.div(
+ 'Usage: $0\n <regex>\t my awesome regex\n <glob>\t my awesome glob\t [required]'
+ )
+ var expected = [
+ 'Usage: $0',
+ ' <regex> my awesome regex',
+ ' <glob> my awesome [required]',
+ ' glob'
+ ]
+
+ ui.toString().split('\n').should.eql(expected)
+ })
+
+ it('aligns rows appropriately when they contain ansi escape codes', function () {
+ var ui = cliui({
+ width: 40
+ })
+
+ ui.div(
+ ' <regex>\t ' + chalk.red('my awesome regex') + '\t [regex]\n ' + chalk.blue('<glob>') + '\t my awesome glob\t [required]'
+ )
+
+ var expected = [
+ ' <regex> my awesome [regex]',
+ ' regex',
+ ' <glob> my awesome [required]',
+ ' glob'
+ ]
+
+ ui.toString().split('\n').map(function (l) {
+ return stripAnsi(l)
+ }).should.eql(expected)
+ })
+
+ it('ignores ansi escape codes when measuring padding', function () {
+ var ui = cliui({
+ width: 25
+ })
+
+ // using figlet font 'Shadow' rendering of text 'true' here
+ ui.div(
+ chalk.blue(' | \n __| __| | | _ \\ \n | | | | __/ \n \\__| _| \\__,_| \\___| \n ')
+ )
+
+ // relevant part is first line - leading whitespace should be preserved as left padding
+ var expected = [
+ ' |',
+ ' __| __| | | _ \\',
+ ' | | | | __/',
+ ' \\__| _| \\__,_| \\___|',
+ ' '
+ ]
+
+ ui.toString().split('\n').map(function (l) {
+ return stripAnsi(l)
+ }).should.eql(expected)
+ })
+
+ it('does not apply DSL if wrap is false', function () {
+ var ui = cliui({
+ width: 40,
+ wrap: false
+ })
+
+ ui.div(
+ 'Usage: $0\ttwo\tthree'
+ )
+
+ ui.toString().should.eql('Usage: $0\ttwo\tthree')
+ })
+ })
+})
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/node-cliui.git
More information about the Pkg-javascript-commits
mailing list