diff --git a/curriculum/tools/fixtures/badFencing.md b/curriculum/tools/fixtures/badFencing.md
new file mode 100644
index 0000000000..3b930a288d
--- /dev/null
+++ b/curriculum/tools/fixtures/badFencing.md
@@ -0,0 +1,38 @@
+---
+id: ''
+title: ''
+challengeType: 0
+videoUrl: ''
+---
+
+## Description
+
+
+## Instructions
+
+
+## Tests
+
+```yml
+tests:
+ - text: text
+ testString: testString
+
+```
+
+
+## Challenge Seed
+
+
+## Solution
+
diff --git a/curriculum/tools/fixtures/badYML.md b/curriculum/tools/fixtures/badYML.md
new file mode 100644
index 0000000000..341240de22
--- /dev/null
+++ b/curriculum/tools/fixtures/badYML.md
@@ -0,0 +1,40 @@
+---
+id: ''
+title: ''
+challengeType: 0
+videoUrl: ''
+---
+
+## Description
+
+
+## Instructions
+
+
+## Tests
+
+
+```yml
+tests:
+ - text: text
+ testString: testString
+
+```
+
+
+
+## Challenge Seed
+
+
+## Solution
+
diff --git a/curriculum/tools/fixtures/good.md b/curriculum/tools/fixtures/good.md
new file mode 100644
index 0000000000..b38bdc45f8
--- /dev/null
+++ b/curriculum/tools/fixtures/good.md
@@ -0,0 +1,40 @@
+---
+id: ''
+title: ''
+challengeType: 0
+videoUrl: ''
+---
+
+## Description
+
+
+## Instructions
+
+
+## Tests
+
+
+```yml
+tests:
+ - text: text
+ testString: testString
+
+```
+
+
+
+## Challenge Seed
+
+
+## Solution
+
diff --git a/curriculum/tools/lint.js b/curriculum/tools/lint.js
index 95e9b4ac55..de47fc3758 100644
--- a/curriculum/tools/lint.js
+++ b/curriculum/tools/lint.js
@@ -1,7 +1,7 @@
const markdownlint = require('markdownlint');
const lintYAML = require('./markdown-yaml');
-const lintConfig = require('./.markdownlintrc.js');
+const lintConfig = require('./.markdownlintrc');
const argv = require('yargs').argv;
const isMDRE = /.*\.md$/;
diff --git a/curriculum/tools/lint.test.js b/curriculum/tools/lint.test.js
new file mode 100644
index 0000000000..212f0f2c4c
--- /dev/null
+++ b/curriculum/tools/lint.test.js
@@ -0,0 +1,57 @@
+/* global describe it expect jest beforeEach */
+const path = require('path');
+
+const lint = require('./lint');
+
+describe('markdown linter', () => {
+ let good = { path: path.join(__dirname, './fixtures/good.md') };
+ let badYML = { path: path.join(__dirname, './fixtures/badYML.md') };
+ let badFencing = { path: path.join(__dirname, './fixtures/badFencing.md') };
+ beforeEach(() => {
+ console.log = jest.fn();
+ // the linter signals that a file failed by setting
+ // exitCode to 1, so it needs (re)setting to 0
+ process.exitCode = 0;
+ });
+ afterEach(() => {
+ process.exitCode = 0;
+ });
+
+ it('should pass `good` markdown', done => {
+ function callback() {
+ expect(process.exitCode).toBe(0);
+ done();
+ }
+ lint(good, callback);
+ });
+
+ it('should fail invalid YML blocks', done => {
+ function callback() {
+ expect(process.exitCode).toBe(1);
+ done();
+ }
+ lint(badYML, callback);
+ });
+
+ it('should fail when code fences are not surrounded by newlines', done => {
+ function callback() {
+ expect(process.exitCode).toBe(1);
+ done();
+ }
+ lint(badFencing, callback);
+ });
+
+ it('should write to the console describing the problem', done => {
+ function callback() {
+ const expected =
+ // eslint-disable-next-line max-len
+ 'fixtures/badYML.md: 19: yaml-linter YAML code blocks must be valid [bad indentation of a mapping entry at line 3, column 17:\n testString: testString\n ^] [Context: "```yml"]';
+ expect(console.log.mock.calls.length).toBe(1);
+ expect(console.log.mock.calls[0][0]).toEqual(
+ expect.stringContaining(expected)
+ );
+ done();
+ }
+ lint(badYML, callback);
+ });
+});
diff --git a/package.json b/package.json
index 6736b40483..e66b7484f0 100644
--- a/package.json
+++ b/package.json
@@ -75,7 +75,7 @@
"eslint --fix",
"git add"
],
- "*.md": [
+ "./curriculum/challenges/**/*.md": [
"node ./curriculum/tools/lint",
"git add"
]