Bez popisu

cliui.js 8.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. /* global describe, it */
  2. require('chai').should()
  3. var cliui = require('../')
  4. describe('cliui', function () {
  5. describe('div', function () {
  6. it("wraps text at 'width' if a single column is given", function () {
  7. var ui = cliui({
  8. width: 10
  9. })
  10. ui.div('i am a string that should be wrapped')
  11. ui.toString().split('\n').forEach(function (row) {
  12. row.length.should.be.lte(10)
  13. })
  14. })
  15. it('evenly divides text across columns if multiple columns are given', function () {
  16. var ui = cliui({
  17. width: 40
  18. })
  19. ui.div(
  20. {text: 'i am a string that should be wrapped', width: 15},
  21. 'i am a second string that should be wrapped',
  22. 'i am a third string that should be wrapped'
  23. )
  24. // total width of all columns is <=
  25. // the width cliui is initialized with.
  26. ui.toString().split('\n').forEach(function (row) {
  27. row.length.should.be.lte(40)
  28. })
  29. // it should wrap each column appropriately.
  30. var expected = [
  31. 'i am a string i am a i am a third',
  32. 'that should be second string that',
  33. 'wrapped string that should be',
  34. ' should be wrapped',
  35. ' wrapped'
  36. ]
  37. ui.toString().split('\n').should.eql(expected)
  38. })
  39. it('allows for a blank row to be appended', function () {
  40. var ui = cliui({
  41. width: 40
  42. })
  43. ui.div()
  44. // it should wrap each column appropriately.
  45. var expected = ['']
  46. ui.toString().split('\n').should.eql(expected)
  47. })
  48. })
  49. describe('_columnWidths', function () {
  50. it('uses same width for each column by default', function () {
  51. var ui = cliui({
  52. width: 40
  53. }),
  54. widths = ui._columnWidths([{}, {}, {}])
  55. widths[0].should.equal(13)
  56. widths[1].should.equal(13)
  57. widths[2].should.equal(13)
  58. })
  59. it('divides width over remaining columns if first column has width specified', function () {
  60. var ui = cliui({
  61. width: 40
  62. }),
  63. widths = ui._columnWidths([{width: 20}, {}, {}])
  64. widths[0].should.equal(20)
  65. widths[1].should.equal(10)
  66. widths[2].should.equal(10)
  67. })
  68. it('divides width over remaining columns if middle column has width specified', function () {
  69. var ui = cliui({
  70. width: 40
  71. }),
  72. widths = ui._columnWidths([{}, {width: 10}, {}])
  73. widths[0].should.equal(15)
  74. widths[1].should.equal(10)
  75. widths[2].should.equal(15)
  76. })
  77. it('keeps track of remaining width if multiple columns have width specified', function () {
  78. var ui = cliui({
  79. width: 40
  80. }),
  81. widths = ui._columnWidths([{width: 20}, {width: 12}, {}])
  82. widths[0].should.equal(20)
  83. widths[1].should.equal(12)
  84. widths[2].should.equal(8)
  85. })
  86. it('uses a sane default if impossible widths are specified', function () {
  87. var ui = cliui({
  88. width: 40
  89. }),
  90. widths = ui._columnWidths([{width: 30}, {width: 30}, {padding: [0, 2, 0, 1]}])
  91. widths[0].should.equal(30)
  92. widths[1].should.equal(30)
  93. widths[2].should.equal(4)
  94. })
  95. })
  96. describe('alignment', function () {
  97. it('allows a column to be right aligned', function () {
  98. var ui = cliui({
  99. width: 40
  100. })
  101. ui.div(
  102. 'i am a string',
  103. {text: 'i am a second string', align: 'right'},
  104. 'i am a third string that should be wrapped'
  105. )
  106. // it should right-align the second column.
  107. var expected = [
  108. 'i am a stringi am a secondi am a third',
  109. ' stringstring that',
  110. ' should be',
  111. ' wrapped'
  112. ]
  113. ui.toString().split('\n').should.eql(expected)
  114. })
  115. it('allows a column to be center aligned', function () {
  116. var ui = cliui({
  117. width: 60
  118. })
  119. ui.div(
  120. 'i am a string',
  121. {text: 'i am a second string', align: 'center', padding: [0, 2, 0, 2]},
  122. 'i am a third string that should be wrapped'
  123. )
  124. // it should right-align the second column.
  125. var expected = [
  126. 'i am a string i am a second i am a third string',
  127. ' string that should be',
  128. ' wrapped'
  129. ]
  130. ui.toString().split('\n').should.eql(expected)
  131. })
  132. })
  133. describe('padding', function () {
  134. it('handles left/right padding', function () {
  135. var ui = cliui({
  136. width: 40
  137. })
  138. ui.div(
  139. {text: 'i have padding on my left', padding: [0, 0, 0, 4]},
  140. {text: 'i have padding on my right', padding: [0, 2, 0, 0], align: 'center'},
  141. {text: 'i have no padding', padding: [0, 0, 0, 0]}
  142. )
  143. // it should add left/right padding to columns.
  144. var expected = [
  145. ' i have i have i have no',
  146. ' padding padding on padding',
  147. ' on my my right',
  148. ' left'
  149. ]
  150. ui.toString().split('\n').should.eql(expected)
  151. })
  152. it('handles top/bottom padding', function () {
  153. var ui = cliui({
  154. width: 40
  155. })
  156. ui.div(
  157. 'i am a string',
  158. {text: 'i am a second string', padding: [2, 0, 0, 0]},
  159. {text: 'i am a third string that should be wrapped', padding: [0, 0, 1, 0]}
  160. )
  161. // it should add top/bottom padding to second
  162. // and third columns.
  163. var expected = [
  164. 'i am a string i am a third',
  165. ' string that',
  166. ' i am a secondshould be',
  167. ' string wrapped',
  168. ''
  169. ]
  170. ui.toString().split('\n').should.eql(expected)
  171. })
  172. })
  173. describe('wrap', function () {
  174. it('allows wordwrap to be disabled', function () {
  175. var ui = cliui({
  176. wrap: false
  177. })
  178. ui.div(
  179. {text: 'i am a string', padding: [0, 1, 0, 0]},
  180. {text: 'i am a second string', padding: [0, 2, 0, 0]},
  181. {text: 'i am a third string that should not be wrapped', padding: [0, 0, 0, 2]}
  182. )
  183. ui.toString().should.equal('i am a string i am a second string i am a third string that should not be wrapped')
  184. })
  185. })
  186. describe('span', function () {
  187. it('appends the next row to the end of the prior row if it fits', function () {
  188. var ui = cliui({
  189. width: 40
  190. })
  191. ui.span(
  192. {text: 'i am a string that will be wrapped', width: 30}
  193. )
  194. ui.div(
  195. {text: ' [required] [default: 99]', align: 'right'}
  196. )
  197. var expected = [
  198. 'i am a string that will be',
  199. 'wrapped [required] [default: 99]'
  200. ]
  201. ui.toString().split('\n').should.eql(expected)
  202. })
  203. it('does not append the string if it does not fit on the prior row', function () {
  204. var ui = cliui({
  205. width: 40
  206. })
  207. ui.span(
  208. {text: 'i am a string that will be wrapped', width: 30}
  209. )
  210. ui.div(
  211. {text: 'i am a second row', align: 'left'}
  212. )
  213. var expected = [
  214. 'i am a string that will be',
  215. 'wrapped',
  216. 'i am a second row'
  217. ]
  218. ui.toString().split('\n').should.eql(expected)
  219. })
  220. it('always appends text to prior span if wrap is disabled', function () {
  221. var ui = cliui({
  222. wrap: false,
  223. width: 40
  224. })
  225. ui.span(
  226. {text: 'i am a string that will be wrapped', width: 30}
  227. )
  228. ui.div(
  229. {text: 'i am a second row', align: 'left', padding: [0, 0, 0, 3]}
  230. )
  231. ui.div('a third line')
  232. var expected = [
  233. 'i am a string that will be wrapped i am a second row',
  234. 'a third line'
  235. ]
  236. ui.toString().split('\n').should.eql(expected)
  237. })
  238. })
  239. describe('layoutDSL', function () {
  240. it('turns tab into multiple columns', function () {
  241. var ui = cliui({
  242. width: 60
  243. })
  244. ui.div(
  245. ' <regex> \tmy awesome regex\n <my second thing> \tanother row\t a third column'
  246. )
  247. var expected = [
  248. ' <regex> my awesome regex',
  249. ' <my second thing> another row a third column'
  250. ]
  251. ui.toString().split('\n').should.eql(expected)
  252. })
  253. it('turns newline into multiple rows', function () {
  254. var ui = cliui({
  255. width: 40
  256. })
  257. ui.div(
  258. 'Usage: $0\n <regex>\t my awesome regex\n <glob>\t my awesome glob\t [required]'
  259. )
  260. var expected = [
  261. 'Usage: $0',
  262. ' <regex> my awesome regex',
  263. ' <glob> my awesome [required]',
  264. ' glob'
  265. ]
  266. ui.toString().split('\n').should.eql(expected)
  267. })
  268. it('does not apply DSL if wrap is false', function () {
  269. var ui = cliui({
  270. width: 40,
  271. wrap: false
  272. })
  273. ui.div(
  274. 'Usage: $0\ttwo\tthree'
  275. )
  276. ui.toString().should.eql('Usage: $0\ttwo\tthree')
  277. })
  278. })
  279. })