Skip to content

Commit 0d3dbfb

Browse files
vaindclaude
andcommitted
Add unit tests for normalizeWhitespace and formatBoilerplateHint
These helpers were extracted in the previous refactor but lacked direct unit tests, relying only on indirect coverage through the integration tests. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 6288ebb commit 0d3dbfb

2 files changed

Lines changed: 61 additions & 15 deletions

File tree

danger/dangerfile-utils.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,5 +202,7 @@ module.exports = {
202202
getFlavorConfig,
203203
extractPRFlavor,
204204
extractLegalBoilerplateSection,
205+
normalizeWhitespace,
206+
formatBoilerplateHint,
205207
checkLegalBoilerplate
206208
};

danger/dangerfile-utils.test.js

Lines changed: 59 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
const { describe, it } = require('node:test');
22
const 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

55
describe('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
480480
Content 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

Comments
 (0)