diff --git a/package.json b/package.json index 6b09a987d1..a5f6d50cdc 100644 --- a/package.json +++ b/package.json @@ -109,6 +109,7 @@ "test:api-v3:integration": "gulp test:api-v3:integration", "test:api-v3:integration:separate-server": "gulp test:api-v3:integration:separate-server", "test:api-legacy": "istanbul cover -i \"website/server/**\" --dir coverage/api ./node_modules/mocha/bin/_mocha test/api-legacy", + "test:sanity": "mocha test/sanity --recursive", "test:common": "mocha test/common --recursive", "test:content": "mocha test/content --recursive", "test:karma": "karma start --single-run", diff --git a/tasks/gulp-tests.js b/tasks/gulp-tests.js index 7db299a5c4..56eba559aa 100644 --- a/tasks/gulp-tests.js +++ b/tasks/gulp-tests.js @@ -24,6 +24,7 @@ const TEST_DB_URI = nconf.get('TEST_DB_URI'); const API_V2_TEST_COMMAND = 'npm run test:api-v2:integration'; const API_V3_TEST_COMMAND = 'npm run test:api-v3'; const LEGACY_API_TEST_COMMAND = 'npm run test:api-legacy'; +const SANITY_TEST_COMMAND = 'npm run test:sanity'; const COMMON_TEST_COMMAND = 'npm run test:common'; const CONTENT_TEST_COMMAND = 'npm run test:content'; const CONTENT_OPTIONS = {maxBuffer: 1024 * 500}; @@ -89,6 +90,16 @@ gulp.task('test:prepare', [ 'test:prepare:webdriver' ]); +gulp.task('test:sanity', (cb) => { + let runner = exec( + testBin(SANITY_TEST_COMMAND), + (err, stdout, stderr) => { + cb(err); + } + ); + pipe(runner); +}); + gulp.task('test:common', ['test:prepare:build'], (cb) => { let runner = exec( testBin(COMMON_TEST_COMMAND), @@ -389,6 +400,7 @@ gulp.task('test:api-v3:integration:separate-server', (done) => { gulp.task('test', (done) => { runSequence( + 'test:sanity', 'test:common', 'test:karma', 'test:api-v3:unit', diff --git a/test/sanity/README.md b/test/sanity/README.md new file mode 100644 index 0000000000..c4fb006115 --- /dev/null +++ b/test/sanity/README.md @@ -0,0 +1,9 @@ +# Sanity Tests + +## Babel Paths for Production Environment + +In development, we [transpile at server start](https://github.com/HabitRPG/habitrpg/blob/1ed7e21542519abe7a3c601f396e1a07f9b050ae/website/server/index.js#L6-L8). This allows us to work quickly while developing, but is not suitable for production. So, in production we transpile the server code before the app starts. + +This system means that requiring any files from `common/script` in `website/server/**/*.js` must be done through the `common/index.js` module. In development, it'll pass through to the pre-transpiled files, but in production it'll point to the transpiled versions. If you try to require or import a file directly, it will error in production as the server doesn't know what to do with some es2015isms (such as the import statement). + +This test just verifies that none of the files in the server code are calling the common files directly. diff --git a/test/sanity/use-proper-babel-path.js b/test/sanity/use-proper-babel-path.js new file mode 100644 index 0000000000..b70403bece --- /dev/null +++ b/test/sanity/use-proper-babel-path.js @@ -0,0 +1,27 @@ +'use strict'; + +let glob = require('glob').sync; +let readFile = require('fs').readFileSync; + +const IMPORT_REGEX = /(import|require).*common\/script/; + +describe('Use Proper Babel Paths', () => { + it('uses proper babel files in website/server', () => { + let websiteServerPaths = glob('./website/server/**/*.js'); + + if (websiteServerPaths.length === 0) { + throw new Error('Could not find any files in website/server/**/*.js'); + } + + websiteServerPaths.forEach((filePath) => { + let file = readFile(filePath, {encoding: 'utf8'}); + + try { + expect(file).to.not.match(IMPORT_REGEX); + } catch (err) { + // Nicer error reporting if this condition is violated + throw new Error(`${filePath} contains an invalid import statement to common/script, which will work in development but fail in production. See README in this directory for more details.`); + } + }); + }); +});