1ffe3c632Sopenharmony_ci/** 2ffe3c632Sopenharmony_ci * @fileoverview Utility to translate test files to CommonJS imports. 3ffe3c632Sopenharmony_ci * 4ffe3c632Sopenharmony_ci * This is a somewhat hacky tool designed to do one very specific thing. 5ffe3c632Sopenharmony_ci * All of the test files in *_test.js are written with Closure-style 6ffe3c632Sopenharmony_ci * imports (goog.require()). This works great for running the tests 7ffe3c632Sopenharmony_ci * against Closure-style generated code, but we also want to run the 8ffe3c632Sopenharmony_ci * tests against CommonJS-style generated code without having to fork 9ffe3c632Sopenharmony_ci * the tests. 10ffe3c632Sopenharmony_ci * 11ffe3c632Sopenharmony_ci * Closure-style imports import each individual type by name. This is 12ffe3c632Sopenharmony_ci * very different than CommonJS imports which are by file. So we put 13ffe3c632Sopenharmony_ci * special comments in these tests like: 14ffe3c632Sopenharmony_ci * 15ffe3c632Sopenharmony_ci * // CommonJS-LoadFromFile: test_pb 16ffe3c632Sopenharmony_ci * goog.require('proto.jspb.test.CloneExtension'); 17ffe3c632Sopenharmony_ci * goog.require('proto.jspb.test.Complex'); 18ffe3c632Sopenharmony_ci * goog.require('proto.jspb.test.DefaultValues'); 19ffe3c632Sopenharmony_ci * 20ffe3c632Sopenharmony_ci * This script parses that special comment and uses it to generate proper 21ffe3c632Sopenharmony_ci * CommonJS require() statements so that the tests can run and pass using 22ffe3c632Sopenharmony_ci * CommonJS imports. The script will change the above statements into: 23ffe3c632Sopenharmony_ci * 24ffe3c632Sopenharmony_ci * var test_pb = require('test_pb'); 25ffe3c632Sopenharmony_ci * googleProtobuf.exportSymbol('proto.jspb.test.CloneExtension', test_pb.CloneExtension, global); 26ffe3c632Sopenharmony_ci * googleProtobuf.exportSymbol('proto.jspb.test.Complex', test_pb.Complex, global); 27ffe3c632Sopenharmony_ci * googleProtobuf.exportSymbol('proto.jspb.test.DefaultValues', test_pb.DefaultValues, global); 28ffe3c632Sopenharmony_ci * 29ffe3c632Sopenharmony_ci * (The "exportSymbol" function will define the given names in the global 30ffe3c632Sopenharmony_ci * namespace, taking care not to overwrite any previous value for 31ffe3c632Sopenharmony_ci * "proto.jspb.test"). 32ffe3c632Sopenharmony_ci */ 33ffe3c632Sopenharmony_ci 34ffe3c632Sopenharmony_civar lineReader = require('readline').createInterface({ 35ffe3c632Sopenharmony_ci input: process.stdin, 36ffe3c632Sopenharmony_ci output: process.stdout 37ffe3c632Sopenharmony_ci}); 38ffe3c632Sopenharmony_ci 39ffe3c632Sopenharmony_cifunction tryStripPrefix(str, prefix) { 40ffe3c632Sopenharmony_ci if (str.lastIndexOf(prefix) !== 0) { 41ffe3c632Sopenharmony_ci throw "String: " + str + " didn't start with: " + prefix; 42ffe3c632Sopenharmony_ci } 43ffe3c632Sopenharmony_ci return str.substr(prefix.length); 44ffe3c632Sopenharmony_ci} 45ffe3c632Sopenharmony_ci 46ffe3c632Sopenharmony_cifunction camelCase(str) { 47ffe3c632Sopenharmony_ci var ret = ''; 48ffe3c632Sopenharmony_ci var ucaseNext = false; 49ffe3c632Sopenharmony_ci for (var i = 0; i < str.length; i++) { 50ffe3c632Sopenharmony_ci if (str[i] == '-') { 51ffe3c632Sopenharmony_ci ucaseNext = true; 52ffe3c632Sopenharmony_ci } else if (ucaseNext) { 53ffe3c632Sopenharmony_ci ret += str[i].toUpperCase(); 54ffe3c632Sopenharmony_ci ucaseNext = false; 55ffe3c632Sopenharmony_ci } else { 56ffe3c632Sopenharmony_ci ret += str[i]; 57ffe3c632Sopenharmony_ci } 58ffe3c632Sopenharmony_ci } 59ffe3c632Sopenharmony_ci return ret; 60ffe3c632Sopenharmony_ci} 61ffe3c632Sopenharmony_ci 62ffe3c632Sopenharmony_civar module = null; 63ffe3c632Sopenharmony_civar pkg = null; 64ffe3c632Sopenharmony_ci 65ffe3c632Sopenharmony_ci// Header: goes in every file at the top. 66ffe3c632Sopenharmony_ciconsole.log("var global = Function('return this')();"); 67ffe3c632Sopenharmony_ciconsole.log("var googleProtobuf = require('google-protobuf');"); 68ffe3c632Sopenharmony_ciconsole.log("var testdeps = require('testdeps_commonjs');"); 69ffe3c632Sopenharmony_ciconsole.log("global.goog = testdeps.goog;"); 70ffe3c632Sopenharmony_ciconsole.log("global.jspb = testdeps.jspb;"); 71ffe3c632Sopenharmony_ciconsole.log("var asserts = require('closure_asserts_commonjs');"); 72ffe3c632Sopenharmony_ciconsole.log(""); 73ffe3c632Sopenharmony_ciconsole.log("// Bring asserts into the global namespace."); 74ffe3c632Sopenharmony_ciconsole.log("googleProtobuf.object.extend(global, asserts);"); 75ffe3c632Sopenharmony_ci 76ffe3c632Sopenharmony_cilineReader.on('line', function(line) { 77ffe3c632Sopenharmony_ci var isRequire = line.match(/goog\.require\('([^']*)'\)/); 78ffe3c632Sopenharmony_ci var isLoadFromFile = line.match(/CommonJS-LoadFromFile: (\S*) (.*)/); 79ffe3c632Sopenharmony_ci var isSetTestOnly = line.match(/goog.setTestOnly()/); 80ffe3c632Sopenharmony_ci if (isRequire) { 81ffe3c632Sopenharmony_ci if (module) { // Skip goog.require() lines before the first directive. 82ffe3c632Sopenharmony_ci var fullSym = isRequire[1]; 83ffe3c632Sopenharmony_ci var sym = tryStripPrefix(fullSym, pkg); 84ffe3c632Sopenharmony_ci console.log("googleProtobuf.exportSymbol('" + fullSym + "', " + module + sym + ', global);'); 85ffe3c632Sopenharmony_ci } 86ffe3c632Sopenharmony_ci } else if (isLoadFromFile) { 87ffe3c632Sopenharmony_ci var module_path = isLoadFromFile[1].split('/'); 88ffe3c632Sopenharmony_ci module = camelCase(module_path[module_path.length - 1]); 89ffe3c632Sopenharmony_ci pkg = isLoadFromFile[2]; 90ffe3c632Sopenharmony_ci 91ffe3c632Sopenharmony_ci if (module != "googleProtobuf") { // We unconditionally require this in the header. 92ffe3c632Sopenharmony_ci console.log("var " + module + " = require('./" + isLoadFromFile[1] + "');"); 93ffe3c632Sopenharmony_ci } 94ffe3c632Sopenharmony_ci } else if (!isSetTestOnly) { // Remove goog.setTestOnly() lines. 95ffe3c632Sopenharmony_ci console.log(line); 96ffe3c632Sopenharmony_ci } 97ffe3c632Sopenharmony_ci}); 98