wrap-text.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. /*
  2. * Copyright (C) 2024 Puter Technologies Inc.
  3. *
  4. * This file is part of Phoenix Shell.
  5. *
  6. * Phoenix Shell is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU Affero General Public License as published
  8. * by the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU Affero General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Affero General Public License
  17. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  18. */
  19. import assert from 'assert';
  20. import { lengthIgnoringEscapes, wrapText } from '../src/util/wrap-text.js';
  21. describe('wrapText', () => {
  22. const testCases = [
  23. {
  24. description: 'should wrap text',
  25. input: 'Well, hello friends! How are you today?',
  26. width: 12,
  27. output: ['Well, hello', 'friends! How', 'are you', 'today?'],
  28. },
  29. {
  30. description: 'should break too-long words onto multiple lines',
  31. input: 'Antidisestablishmentarianism.',
  32. width: 20,
  33. output: ['Antidisestablishmen-', 'tarianism.'],
  34. },
  35. {
  36. description: 'should break too-long words onto multiple lines',
  37. input: 'Antidisestablishmentarianism.',
  38. width: 10,
  39. output: ['Antidises-', 'tablishme-', 'ntarianis-', 'm.'],
  40. },
  41. {
  42. description: 'should break too-long words when there is already text on the line',
  43. input: 'The longest word I can think of is antidisestablishmentarianism.',
  44. width: 20,
  45. output: ['The longest word I', 'can think of is', 'antidisestablishmen-', 'tarianism.'],
  46. },
  47. {
  48. description: 'should return the original text if the width is invalid',
  49. input: 'Well, hello friends!',
  50. width: 0,
  51. output: ['Well, hello friends!'],
  52. },
  53. {
  54. description: 'should maintain existing newlines',
  55. input: 'Well\nhello\n\nfriends!',
  56. width: 20,
  57. output: ['Well', 'hello', '', 'friends!'],
  58. },
  59. {
  60. description: 'should maintain indentation after newlines',
  61. input: 'Well\n hello\n\nfriends!',
  62. width: 20,
  63. output: ['Well', ' hello', '', 'friends!'],
  64. },
  65. {
  66. description: 'should ignore ansi escape sequences',
  67. input: '\x1B[34;1mWell this is some text with ansi escape sequences\x1B[0m',
  68. width: 20,
  69. output: ['\x1B[34;1mWell this is some', 'text with ansi', 'escape sequences\x1B[0m'],
  70. },
  71. ];
  72. for (const { description, input, width, output } of testCases) {
  73. it (description, () => {
  74. const result = wrapText(input, width);
  75. for (const line of result) {
  76. if (typeof width === 'number' && width > 0) {
  77. assert.ok(lengthIgnoringEscapes(line) <= width, `Line is too long: '${line}'`);
  78. }
  79. }
  80. assert.equal('|' + result.join('|\n|') + '|', '|' + output.join('|\n|') + '|');
  81. });
  82. }
  83. })