diff --git a/jest/preprocessor.js b/jest/preprocessor.js index d52482c816..b8451458b7 100644 --- a/jest/preprocessor.js +++ b/jest/preprocessor.js @@ -3,7 +3,14 @@ var ReactTools = require('../main.js'); var coffee = require('coffee-script'); -var ts = require('ts-compiler'); +var tsPreprocessor = require('./ts-preprocessor'); + +var defaultLibraries = [ + require.resolve('./jest.d.ts'), + require.resolve('../src/modern/class/React.d.ts') +]; + +var ts = tsPreprocessor(defaultLibraries); module.exports = { process: function(src, path) { @@ -11,20 +18,7 @@ module.exports = { return coffee.compile(src, {'bare': true}); } if (path.match(/\.ts$/) && !path.match(/\.d\.ts$/)) { - ts.compile([path], { - skipWrite: true, - module: 'commonjs' - }, function(err, results) { - if (err) { - throw err; - } - results.forEach(function(file) { - // This is gross, but jest doesn't provide an asynchronous way to - // process a module, and ts currently runs syncronously. - src = file.text; - }); - }); - return src; + return ts.compile(src, path); } return ReactTools.transform(src, {harmony: true}); } diff --git a/jest/ts-preprocessor.js b/jest/ts-preprocessor.js new file mode 100644 index 0000000000..cc9ede50f7 --- /dev/null +++ b/jest/ts-preprocessor.js @@ -0,0 +1,67 @@ +'use strict'; + +var fs = require('fs'); +var path = require('path'); +var ts = require('typescript'); + +var tsOptions = { module: 'commonjs' }; + +function formatErrorMessage(error) { + return ( + error.file.filename + '(' + + error.file.getLineAndCharacterFromPosition(error.start).line + + '): ' + + error.messageText + ); +} + +function compile(defaultLib, content, contentFilename) { + var output = null; + var compilerHost = { + getSourceFile: function(filename, languageVersion) { + if (filename === contentFilename) { + return ts.createSourceFile(filename, content, 'ES5', '0'); + } + return defaultLib; + }, + writeFile: function(name, text, writeByteOrderMark) { + if (output === null) { + output = text; + } else { + throw new Error('Expected only one dependency.'); + } + }, + getCanonicalFileName: function(filename) { return filename; }, + getCurrentDirectory: function() { return ''; }, + getNewLine: function() { return '\n'; } + }; + var program = ts.createProgram([contentFilename], tsOptions, compilerHost); + var errors = program.getDiagnostics(); + if (!errors.length) { + var checker = program.getTypeChecker(true); + errors = checker.getDiagnostics(); + checker.emitFiles(); + } + if (errors.length) { + throw new Error(errors.map(formatErrorMessage).join('\n')); + } + return output; +} + +module.exports = function(defaultLibs) { + var defaultLibSource = fs.readFileSync( + path.join(path.dirname(require.resolve('typescript')), 'lib.d.ts') + ); + + for (var i = 0; i < defaultLibs.length; i++) { + defaultLibSource += '\n' + fs.readFileSync(defaultLibs[i]); + } + + var defaultLibSourceFile = ts.createSourceFile( + 'lib.d.ts', defaultLibSource, 'ES5' + ); + + return { + compile: compile.bind(null, defaultLibSourceFile) + }; +}; diff --git a/package.json b/package.json index 3256a65bd4..6f14eaa037 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,7 @@ "recast": "^0.9.11", "sauce-tunnel": "~1.1.0", "tmp": "~0.0.18", - "ts-compiler": "^2.0.0", + "typescript": "^1.4.0", "uglify-js": "~2.4.0", "uglifyify": "^2.4.0", "wd": "~0.2.6" diff --git a/src/modern/class/__tests__/ReactTypeScriptClass-test.ts b/src/modern/class/__tests__/ReactTypeScriptClass-test.ts index ec21ce8012..eb447a8ce3 100644 --- a/src/modern/class/__tests__/ReactTypeScriptClass-test.ts +++ b/src/modern/class/__tests__/ReactTypeScriptClass-test.ts @@ -7,9 +7,6 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -/// -/// - import React = require('React'); // Before Each