1'use strict'; 2require('../common'); 3const { 4 hijackStdout, 5 hijackStderr, 6 restoreStdout, 7 restoreStderr 8} = require('../common/hijackstdio'); 9 10const assert = require('assert'); 11const Console = require('console').Console; 12 13let c, stdout, stderr; 14 15function setup(groupIndentation) { 16 stdout = ''; 17 hijackStdout(function(data) { 18 stdout += data; 19 }); 20 21 stderr = ''; 22 hijackStderr(function(data) { 23 stderr += data; 24 }); 25 26 c = new Console({ stdout: process.stdout, 27 stderr: process.stderr, 28 colorMode: false, 29 groupIndentation: groupIndentation }); 30} 31 32function teardown() { 33 restoreStdout(); 34 restoreStderr(); 35} 36 37// Basic group() functionality 38{ 39 setup(); 40 const expectedOut = 'This is the outer level\n' + 41 ' Level 2\n' + 42 ' Level 3\n' + 43 ' Back to level 2\n' + 44 'Back to the outer level\n' + 45 'Still at the outer level\n'; 46 47 48 const expectedErr = ' More of level 3\n'; 49 50 c.log('This is the outer level'); 51 c.group(); 52 c.log('Level 2'); 53 c.group(); 54 c.log('Level 3'); 55 c.warn('More of level 3'); 56 c.groupEnd(); 57 c.log('Back to level 2'); 58 c.groupEnd(); 59 c.log('Back to the outer level'); 60 c.groupEnd(); 61 c.log('Still at the outer level'); 62 63 assert.strictEqual(stdout, expectedOut); 64 assert.strictEqual(stderr, expectedErr); 65 teardown(); 66} 67 68// Group indentation is tracked per Console instance. 69{ 70 setup(); 71 const expectedOut = 'No indentation\n' + 72 'None here either\n' + 73 ' Now the first console is indenting\n' + 74 'But the second one does not\n'; 75 const expectedErr = ''; 76 77 const c2 = new Console(process.stdout, process.stderr); 78 c.log('No indentation'); 79 c2.log('None here either'); 80 c.group(); 81 c.log('Now the first console is indenting'); 82 c2.log('But the second one does not'); 83 84 assert.strictEqual(stdout, expectedOut); 85 assert.strictEqual(stderr, expectedErr); 86 teardown(); 87} 88 89// Make sure labels work. 90{ 91 setup(); 92 const expectedOut = 'This is a label\n' + 93 ' And this is the data for that label\n'; 94 const expectedErr = ''; 95 96 c.group('This is a label'); 97 c.log('And this is the data for that label'); 98 99 assert.strictEqual(stdout, expectedOut); 100 assert.strictEqual(stderr, expectedErr); 101 teardown(); 102} 103 104// Check that console.groupCollapsed() is an alias of console.group() 105{ 106 setup(); 107 const expectedOut = 'Label\n' + 108 ' Level 2\n' + 109 ' Level 3\n'; 110 const expectedErr = ''; 111 112 c.groupCollapsed('Label'); 113 c.log('Level 2'); 114 c.groupCollapsed(); 115 c.log('Level 3'); 116 117 assert.strictEqual(stdout, expectedOut); 118 assert.strictEqual(stderr, expectedErr); 119 teardown(); 120} 121 122// Check that multiline strings and object output are indented properly. 123{ 124 setup(); 125 const expectedOut = 'not indented\n' + 126 ' indented\n' + 127 ' also indented\n' + 128 ' {\n' + 129 " also: 'a',\n" + 130 " multiline: 'object',\n" + 131 " should: 'be',\n" + 132 " indented: 'properly',\n" + 133 " kthx: 'bai'\n" + 134 ' }\n'; 135 const expectedErr = ''; 136 137 c.log('not indented'); 138 c.group(); 139 c.log('indented\nalso indented'); 140 c.log({ also: 'a', 141 multiline: 'object', 142 should: 'be', 143 indented: 'properly', 144 kthx: 'bai' }); 145 146 assert.strictEqual(stdout, expectedOut); 147 assert.strictEqual(stderr, expectedErr); 148 teardown(); 149} 150 151// Check that the kGroupIndent symbol property is not enumerable 152{ 153 const keys = Reflect.ownKeys(console) 154 .filter((val) => console.propertyIsEnumerable(val)) 155 .map((val) => val.toString()); 156 assert(!keys.includes('Symbol(groupIndent)'), 157 'groupIndent should not be enumerable'); 158} 159 160// Check custom groupIndentation. 161{ 162 setup(3); 163 const expectedOut = 'Set the groupIndentation parameter to 3\n' + 164 'This is the outer level\n' + 165 ' Level 2\n' + 166 ' Level 3\n' + 167 ' Back to level 2\n' + 168 'Back to the outer level\n' + 169 'Still at the outer level\n'; 170 171 172 const expectedErr = ' More of level 3\n'; 173 174 c.log('Set the groupIndentation parameter to 3'); 175 c.log('This is the outer level'); 176 c.group(); 177 c.log('Level 2'); 178 c.group(); 179 c.log('Level 3'); 180 c.warn('More of level 3'); 181 c.groupEnd(); 182 c.log('Back to level 2'); 183 c.groupEnd(); 184 c.log('Back to the outer level'); 185 c.groupEnd(); 186 c.log('Still at the outer level'); 187 188 assert.strictEqual(stdout, expectedOut); 189 assert.strictEqual(stderr, expectedErr); 190 teardown(); 191} 192 193// Check the correctness of the groupIndentation parameter. 194{ 195 // TypeError 196 [null, 'str', [], false, true, {}].forEach((e) => { 197 assert.throws( 198 () => { 199 new Console({ stdout: process.stdout, 200 stderr: process.stderr, 201 groupIndentation: e }); 202 }, 203 { 204 code: 'ERR_INVALID_ARG_TYPE', 205 name: 'TypeError' 206 } 207 ); 208 }); 209 210 // RangeError for integer 211 [NaN, 1.01].forEach((e) => { 212 assert.throws( 213 () => { 214 new Console({ stdout: process.stdout, 215 stderr: process.stderr, 216 groupIndentation: e }); 217 }, 218 { 219 code: 'ERR_OUT_OF_RANGE', 220 name: 'RangeError', 221 message: /an integer/, 222 } 223 ); 224 }); 225 226 // RangeError 227 [-1, 1001].forEach((e) => { 228 assert.throws( 229 () => { 230 new Console({ stdout: process.stdout, 231 stderr: process.stderr, 232 groupIndentation: e }); 233 }, 234 { 235 code: 'ERR_OUT_OF_RANGE', 236 name: 'RangeError', 237 message: />= 0 && <= 1000/, 238 } 239 ); 240 }); 241} 242