11const { describe, it } = require ( 'node:test' ) ;
22const assert = require ( 'node:assert' ) ;
3- const { getFlavorConfig, extractPRFlavor, extractLegalBoilerplateSection, checkLegalBoilerplate, FLAVOR_CONFIG } = require ( './dangerfile-utils.js' ) ;
3+ const { getFlavorConfig, extractPRFlavor, extractLegalBoilerplateSection, normalizeWhitespace , formatBoilerplateHint , checkLegalBoilerplate, FLAVOR_CONFIG } = require ( './dangerfile-utils.js' ) ;
44
55describe ( 'dangerfile-utils' , ( ) => {
66 describe ( 'getFlavorConfig' , ( ) => {
@@ -292,7 +292,7 @@ Look, I get it. The entity doing business as "Sentry" was incorporated in the St
292292` ;
293293
294294 const result = extractLegalBoilerplateSection ( template ) ;
295-
295+
296296 assert . ok ( result . includes ( '### Legal Boilerplate' ) , 'Should include the header' ) ;
297297 assert . ok ( result . includes ( 'Functional Software, Inc.' ) , 'Should include the legal text' ) ;
298298 assert . ok ( ! result . includes ( '## Checklist' ) , 'Should not include the next section' ) ;
@@ -311,7 +311,7 @@ More content
311311` ;
312312
313313 const result = extractLegalBoilerplateSection ( template ) ;
314-
314+
315315 assert . strictEqual ( result . trim ( ) , '## Legal Boilerplate\n\nThis is a legal notice.' ) ;
316316 } ) ;
317317
@@ -328,7 +328,7 @@ More content
328328 testCases . forEach ( ( { header, text } ) => {
329329 const template = `${ header } \n${ text } \n## Next Section` ;
330330 const result = extractLegalBoilerplateSection ( template ) ;
331-
331+
332332 assert . ok ( result . includes ( header ) , `Should extract section with ${ header } ` ) ;
333333 assert . ok ( result . includes ( text ) , `Should include text for ${ header } ` ) ;
334334 assert . ok ( ! result . includes ( 'Next Section' ) , `Should not include next section for ${ header } ` ) ;
@@ -364,7 +364,7 @@ Third paragraph of legal text.
364364` ;
365365
366366 const result = extractLegalBoilerplateSection ( template ) ;
367-
367+
368368 assert . ok ( result . includes ( 'First paragraph' ) , 'Should include first paragraph' ) ;
369369 assert . ok ( result . includes ( 'Second paragraph' ) , 'Should include second paragraph' ) ;
370370 assert . ok ( result . includes ( 'Third paragraph' ) , 'Should include third paragraph' ) ;
@@ -383,7 +383,7 @@ Legal text at the end.
383383` ;
384384
385385 const result = extractLegalBoilerplateSection ( template ) ;
386-
386+
387387 assert . ok ( result . includes ( '### Legal Boilerplate' ) , 'Should include header' ) ;
388388 assert . ok ( result . includes ( 'Legal text at the end.' ) , 'Should include text' ) ;
389389 } ) ;
@@ -400,7 +400,7 @@ Please describe your changes
400400` ;
401401
402402 const result = extractLegalBoilerplateSection ( template ) ;
403-
403+
404404 assert . strictEqual ( result , '' , 'Should return empty string when no legal section found' ) ;
405405 } ) ;
406406
@@ -412,7 +412,7 @@ Please describe your changes
412412 it ( 'should handle template with only legal boilerplate section' , ( ) => {
413413 const template = '### Legal Boilerplate\nThis is the only content.' ;
414414 const result = extractLegalBoilerplateSection ( template ) ;
415-
415+
416416 assert . ok ( result . includes ( '### Legal Boilerplate' ) , 'Should include header' ) ;
417417 assert . ok ( result . includes ( 'This is the only content.' ) , 'Should include content' ) ;
418418 } ) ;
@@ -427,7 +427,7 @@ And some unicode: 你好世界 🎉
427427` ;
428428
429429 const result = extractLegalBoilerplateSection ( template ) ;
430-
430+
431431 assert . ok ( result . includes ( 'special chars' ) , 'Should handle special characters' ) ;
432432 assert . ok ( result . includes ( '你好世界' ) , 'Should handle unicode' ) ;
433433 assert . ok ( result . includes ( '🎉' ) , 'Should handle emoji' ) ;
@@ -449,7 +449,7 @@ More text.
449449` ;
450450
451451 const result = extractLegalBoilerplateSection ( template ) ;
452-
452+
453453 assert . ok ( result . includes ( 'const legal = true;' ) , 'Should include code blocks' ) ;
454454 assert . ok ( result . includes ( 'More text.' ) , 'Should include text after code block' ) ;
455455 assert . ok ( ! result . includes ( 'Next Section' ) , 'Should not include next section' ) ;
@@ -468,21 +468,21 @@ You agree to:
468468` ;
469469
470470 const result = extractLegalBoilerplateSection ( template ) ;
471-
471+
472472 assert . ok ( result . includes ( '- Item 1' ) , 'Should include list items' ) ;
473473 assert . ok ( result . includes ( '- Item 2' ) , 'Should include list items' ) ;
474474 assert . ok ( result . includes ( '- Item 3' ) , 'Should include list items' ) ;
475475 } ) ;
476476
477477 it ( 'should handle legal boilerplate with extra whitespace' , ( ) => {
478478 const template = `
479- ### Legal Boilerplate
479+ ### Legal Boilerplate
480480Content with spaces.
481481## Next
482482` ;
483483
484484 const result = extractLegalBoilerplateSection ( template ) ;
485-
485+
486486 assert . ok ( result . includes ( 'Content with spaces.' ) , 'Should handle extra whitespace in header' ) ;
487487 } ) ;
488488
@@ -495,7 +495,7 @@ This should not be included.
495495` ;
496496
497497 const result = extractLegalBoilerplateSection ( template ) ;
498-
498+
499499 assert . ok ( result . includes ( 'First section content.' ) , 'Should include first section' ) ;
500500 assert . ok ( ! result . includes ( 'This should not be included.' ) , 'Should stop at next header' ) ;
501501 } ) ;
@@ -522,6 +522,50 @@ Second paragraph with blank lines above.
522522 } ) ;
523523 } ) ;
524524
525+ describe ( 'normalizeWhitespace' , ( ) => {
526+ it ( 'should collapse multiple spaces into one' , ( ) => {
527+ assert . strictEqual ( normalizeWhitespace ( 'hello world' ) , 'hello world' ) ;
528+ } ) ;
529+
530+ it ( 'should collapse tabs and newlines into spaces' , ( ) => {
531+ assert . strictEqual ( normalizeWhitespace ( "hello\t\nworld" ) , 'hello world' ) ;
532+ } ) ;
533+
534+ it ( 'should trim leading and trailing whitespace' , ( ) => {
535+ assert . strictEqual ( normalizeWhitespace ( ' hello world ' ) , 'hello world' ) ;
536+ } ) ;
537+
538+ it ( 'should return empty string for whitespace-only input' , ( ) => {
539+ assert . strictEqual ( normalizeWhitespace ( ' \t\n ' ) , '' ) ;
540+ } ) ;
541+
542+ it ( 'should leave single-spaced text unchanged' , ( ) => {
543+ assert . strictEqual ( normalizeWhitespace ( 'already clean' ) , 'already clean' ) ;
544+ } ) ;
545+ } ) ;
546+
547+ describe ( 'formatBoilerplateHint' , ( ) => {
548+ it ( 'should include the title with emoji prefix' , ( ) => {
549+ const result = formatBoilerplateHint ( 'My Title' , 'Some description.' , 'boilerplate text' ) ;
550+ assert . ok ( result . includes ( '### ⚖️ My Title' ) ) ;
551+ } ) ;
552+
553+ it ( 'should include the description' , ( ) => {
554+ const result = formatBoilerplateHint ( 'Title' , 'Please fix this.' , 'boilerplate' ) ;
555+ assert . ok ( result . includes ( 'Please fix this.' ) ) ;
556+ } ) ;
557+
558+ it ( 'should include the boilerplate in a markdown code block' , ( ) => {
559+ const result = formatBoilerplateHint ( 'Title' , 'Desc' , 'expected legal text' ) ;
560+ assert . ok ( result . includes ( '```markdown\nexpected legal text\n```' ) ) ;
561+ } ) ;
562+
563+ it ( 'should include the IP rights notice' , ( ) => {
564+ const result = formatBoilerplateHint ( 'Title' , 'Desc' , 'text' ) ;
565+ assert . ok ( result . includes ( 'intellectual property rights' ) ) ;
566+ } ) ;
567+ } ) ;
568+
525569 describe ( 'checkLegalBoilerplate' , ( ) => {
526570 const PR_TEMPLATE_WITH_BOILERPLATE = `# Pull Request Template
527571
@@ -756,4 +800,4 @@ Look, I get it. The entity doing business as "Sentry" was incorporated in the St
756800 assert . ok ( ctx . markdownMessages [ 0 ] . includes ( 'Functional Software, Inc.' ) ) ;
757801 } ) ;
758802 } ) ;
759- } ) ;
803+ } ) ;
0 commit comments