Skip to content

Commit

Permalink
Add automated tests for validation script (#438)
Browse files Browse the repository at this point in the history
* Update node

* Add mocha and chai

* Fix npm audit issue

https://nodesecurity.io/advisories/577

* Skip some redundant errors

* Catch duplicate headings

* Update the wording of a few errors

* Detect when headings are wrapped inside another element

* Build and validate the content of each profile section

* Add tests for validation script

* Remove empty sections in existing profiles
  • Loading branch information
nylen committed Jun 23, 2018
1 parent be43568 commit 8942a91
Show file tree
Hide file tree
Showing 59 changed files with 1,962 additions and 51 deletions.
2 changes: 1 addition & 1 deletion .nvmrc
@@ -1 +1 @@
v9.3.0
v10.5.0
2 changes: 1 addition & 1 deletion .travis.yml
Expand Up @@ -2,4 +2,4 @@ language: node_js

before_script: npm install

script: node bin/validate.js
script: node bin/validate.js && node node_modules/.bin/mocha
75 changes: 72 additions & 3 deletions bin/validate.js
Expand Up @@ -171,11 +171,20 @@ profileFilenames.forEach( filename => {
);
const $ = cheerio.load( marked( profileMarkdown ) );

let hasTitleError = false;

if ( $( 'h1' ).length !== 1 ) {
error(
'Expected 1 first-level heading but found %d',
$( 'h1' ).length
);
hasTitleError = true;
}

if ( ! $( 'h1' ).parent().is( 'body' ) ) {
error(
'The main title is wrapped inside of another element.'
);
}

const companyName = $( 'h1' ).text();
Expand All @@ -185,11 +194,13 @@ profileFilenames.forEach( filename => {
'Company name looks wrong: "%s"',
companyName
);
hasTitleError = true;
}

const filenameBase = filename.replace( /\.md$/, '' );
const filenameExpected = companyNameToProfileFilename( companyName );
if (
! hasTitleError &&
filenameBase !== filenameExpected &&
// Some profile files just have shorter names than the company name,
// which is fine.
Expand All @@ -215,17 +226,35 @@ profileFilenames.forEach( filename => {

$( 'h2' ).each( ( i, el ) => {
const headingName = $( el ).html();
profileHeadings.push( headingName );

if ( ! $( el ).parent().is( 'body' ) ) {
error(
'The section heading for "%s" is wrapped inside of another element.',
headingName
);
}

if ( profileHeadings.indexOf( headingName ) >= 0 ) {
error(
'Duplicate section: "%s".',
headingName
);
}

if (
headingsRequired.indexOf( headingName ) === -1 &&
headingsOptional.indexOf( headingName ) === -1
) {
error(
'Invalid heading name: "%s". Expected one of: %s',
'Invalid section: "%s". Expected one of: %s',
headingName,
JSON.stringify( headingsRequired.concat( headingsOptional ) )
);
}

// Track headings for this profile
profileHeadings.push( headingName );

// Track headings across all profiles
if ( ! allProfileHeadings[ headingName ] ) {
allProfileHeadings[ headingName ] = [];
Expand All @@ -236,11 +265,51 @@ profileFilenames.forEach( filename => {
headingsRequired.forEach( headingName => {
if ( profileHeadings.indexOf( headingName ) === -1 ) {
error(
'Required heading "%s" not found.',
'Required section "%s" not found.',
headingName
);
}
} );

// Build and validate the content of each section in this profile.

const profileContent = {};
let currentHeading = null;

$( 'body' ).children().each( ( i, el ) => {
const $el = $( el );

if ( $el.is( 'h1' ) ) {
return;
}

if ( $el.is( 'h2' ) ) {
currentHeading = $el.html();
profileContent[ currentHeading ] = '';
} else if ( currentHeading ) {
profileContent[ currentHeading ] = (
profileContent[ currentHeading ]
+ '\n' + $.html( el )
).trim();
} else {
error(
'Content is not part of any section: %s',
$.html( el ).replace( /\n/g, '' )
);
}
} );

Object.keys( profileContent ).forEach( heading => {
const sectionText = profileContent[ heading ]
.replace( /<[^>]+>/g, '' )
.trim();
if ( ! sectionText ) {
error(
'Empty section: "%s". Leave it out instead.',
heading
);
}
} );
} );

if ( process.env.REPORT_PROFILE_HEADINGS ) {
Expand Down
2 changes: 0 additions & 2 deletions company-profiles/bitovi.md
Expand Up @@ -8,8 +8,6 @@ Bitovi simplifies JavaScript development and UX design. We teach people how to c

30-40 employees

## Remote status

## Region

A team of developers (and designers) located around the US, Canada, and Croatia.
Expand Down
2 changes: 0 additions & 2 deletions company-profiles/envato.md
Expand Up @@ -20,8 +20,6 @@ Many roles within Envato are able to work from anywhere (usually from home) if y

Envato is a fast growing company with headquarters in Melbourne.

## Company technologies

## Office locations

Headquarters in Melbourne, Australia. Team located around the world.
Expand Down
6 changes: 0 additions & 6 deletions company-profiles/freeagent.md
Expand Up @@ -8,16 +8,10 @@ FreeAgent is one of the UK's largest, and most popular, online accounting servic

61 listed on Freeagent [About Us](http://www.freeagent.com/company/about-us)

## Remote status


## Region

Scotland, UK based company, remote worldwide

## Company technologies


## Office locations

FreeAgent
Expand Down
2 changes: 0 additions & 2 deletions company-profiles/kissmetrics.md
Expand Up @@ -4,8 +4,6 @@

KissMetrics is focused on helping marketers improve their performance.

## Company size

## Remote status

Most of the team works remotely and everyone has the option of working remotely or from the Headquarters in San Francisco (snacks, nap room, video game room, and a puppy included at HQ!).
Expand Down

0 comments on commit 8942a91

Please sign in to comment.