You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by ag...@apache.org on 2013/01/16 22:34:10 UTC
[1/4] js commit: [all] Implementation of modulemapper + tests.
[all] Implementation of modulemapper + tests.
Project: http://git-wip-us.apache.org/repos/asf/cordova-js/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-js/commit/403d9311
Tree: http://git-wip-us.apache.org/repos/asf/cordova-js/tree/403d9311
Diff: http://git-wip-us.apache.org/repos/asf/cordova-js/diff/403d9311
Branch: refs/heads/symbolmapping
Commit: 403d9311cd30a4a8eaa3f00a88a5f940a7e9a859
Parents: 2e6ebcc
Author: Andrew Grieve <ag...@chromium.org>
Authored: Wed Jan 16 16:33:16 2013 -0500
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Wed Jan 16 16:33:47 2013 -0500
----------------------------------------------------------------------
lib/common/modulemapper.js | 88 +++++++++++++++++++++++
lib/test/testmodule.js | 27 +++++++
test/test.modulemapper.js | 148 +++++++++++++++++++++++++++++++++++++++
3 files changed, 263 insertions(+), 0 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-js/blob/403d9311/lib/common/modulemapper.js
----------------------------------------------------------------------
diff --git a/lib/common/modulemapper.js b/lib/common/modulemapper.js
new file mode 100644
index 0000000..9714618
--- /dev/null
+++ b/lib/common/modulemapper.js
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+var builder = require('cordova/builder'),
+ symbolList,
+ deprecationMap;
+
+exports.reset = function() {
+ symbolList = [];
+ deprecationMap = {};
+};
+
+function addEntry(strategy, moduleName, symbolPath, opt_deprecationMessage) {
+ if (!(moduleName in define.moduleMap)) {
+ throw new Error('Module ' + moduleName + ' does not exist.');
+ }
+ symbolList.push(strategy, moduleName, symbolPath);
+ if (opt_deprecationMessage) {
+ deprecationMap[symbolPath] = opt_deprecationMessage;
+ }
+}
+
+exports.clobbers = addEntry.bind(null, 'c');
+exports.merges = addEntry.bind(null, 'm');
+exports.defaults = addEntry.bind(null, 'd');
+
+function prepareNamespace(symbolPath, context) {
+ if (!symbolPath) {
+ return context;
+ }
+ var parts = symbolPath.split('.');
+ var cur = context;
+ for (var i = 0, part; part = parts[i]; ++i) {
+ cur[part] = cur[part] || {};
+ }
+ return cur[parts[i-1]];
+}
+
+exports.mapModules = function(context) {
+ var origSymbols = {};
+ context.CDV_origSymbols = origSymbols;
+ for (var i = 0, len = symbolList.length; i < len; i += 3) {
+ var strategy = symbolList[i];
+ var moduleName = symbolList[i + 1];
+ var symbolPath = symbolList[i + 2];
+ var lastDot = symbolPath.lastIndexOf('.');
+ var namespace = symbolPath.substr(0, lastDot);
+ var lastName = symbolPath.substr(lastDot + 1);
+
+ var module = require(moduleName);
+ var parentObj = prepareNamespace(namespace, context);
+ var target = parentObj[lastName];
+
+ if (strategy == 'm' && target) {
+ builder.recursiveMerge(target, module);
+ } else if ((strategy == 'd' && !target) || (strategy != 'd')) {
+ if (target) {
+ origSymbols[symbolPath] = target;
+ }
+ builder.clobber(parentObj, lastName, module);
+ }
+ }
+};
+
+exports.getOriginalSymbol = function(context, symbolPath) {
+ var origSymbols = context.CDV_origSymbols;
+ return origSymbols && origSymbols[symbolPath];
+};
+
+exports.reset();
+
http://git-wip-us.apache.org/repos/asf/cordova-js/blob/403d9311/lib/test/testmodule.js
----------------------------------------------------------------------
diff --git a/lib/test/testmodule.js b/lib/test/testmodule.js
new file mode 100644
index 0000000..80eaf94
--- /dev/null
+++ b/lib/test/testmodule.js
@@ -0,0 +1,27 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+module.exports = {
+ func: function() {},
+ num: 2,
+ obj: { str: 'hello' },
+ subObj: { str: 'testSubObj' }
+};
http://git-wip-us.apache.org/repos/asf/cordova-js/blob/403d9311/test/test.modulemapper.js
----------------------------------------------------------------------
diff --git a/test/test.modulemapper.js b/test/test.modulemapper.js
new file mode 100644
index 0000000..826fab2
--- /dev/null
+++ b/test/test.modulemapper.js
@@ -0,0 +1,148 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+describe('modulemapper', function() {
+ var modulemapper = require('cordova/modulemapper'),
+ testmodule = require('cordova/testmodule'),
+ utils = require('cordova/utils');
+ var context;
+
+ beforeEach(function() {
+ function TestClass() {}
+ TestClass.prototype.method1 = function() { return 'orig'; };
+
+ context = {
+ func: function() {},
+ num: 1,
+ obj: { str: 'hello', num: 8, subObj: {num: 9} },
+ TestClass: TestClass
+ };
+ utils.defineGetter(context, 'getme', function() { return 'getter' });
+ });
+
+ afterEach(function() {
+ modulemapper.reset();
+ });
+
+ it('should throw in module does not exist', function() {
+ expect(function() { modulemapper.clobbers('cordova/invalid', 'newProp'); }).toThrow();
+ });
+ it('should properly set a new top-level property', function() {
+ modulemapper.clobbers('cordova/testmodule', 'newProp1');
+ modulemapper.defaults('cordova/testmodule', 'newProp2');
+ modulemapper.merges('cordova/testmodule', 'newProp3');
+ modulemapper.mapModules(context);
+ expect(context.newProp1).toBe(testmodule);
+ expect(context.newProp2).toBe(testmodule);
+ expect(context.newProp3).toBe(testmodule);
+ });
+ it('should properly set a new non-top-level property', function() {
+ modulemapper.clobbers('cordova/testmodule', 'foo1.newProp');
+ modulemapper.defaults('cordova/testmodule', 'foo2.newProp');
+ modulemapper.merges('cordova/testmodule', 'foo3.newProp');
+ modulemapper.mapModules(context);
+ expect(context.foo1.newProp).toBe(testmodule);
+ expect(context.foo2.newProp).toBe(testmodule);
+ expect(context.foo3.newProp).toBe(testmodule);
+ });
+ it('should properly set a non-new non-top-level property', function() {
+ modulemapper.clobbers('cordova/testmodule', 'obj.newProp1');
+ modulemapper.defaults('cordova/testmodule', 'obj.newProp2');
+ modulemapper.merges('cordova/testmodule', 'obj.newProp3');
+ modulemapper.mapModules(context);
+ expect(context.obj.newProp1).toBe(testmodule);
+ expect(context.obj.newProp2).toBe(testmodule);
+ expect(context.obj.newProp3).toBe(testmodule);
+ });
+ it('should clobber existing properties', function() {
+ modulemapper.clobbers('cordova/testmodule', 'num');
+ modulemapper.clobbers('cordova/testmodule', 'obj.str');
+ modulemapper.clobbers('cordova/testmodule', 'getme');
+ modulemapper.clobbers('cordova/testmodule', 'TestClass');
+ modulemapper.mapModules(context);
+ expect(context.num).toBe(testmodule);
+ expect(context.obj.str).toBe(testmodule);
+ expect(context.getme).toBe(testmodule);
+ expect(context.TestClass).toBe(testmodule);
+ });
+ it('should not clobber existing properties when using defaults', function() {
+ modulemapper.defaults('cordova/testmodule', 'num');
+ modulemapper.defaults('cordova/testmodule', 'obj.str');
+ modulemapper.defaults('cordova/testmodule', 'obj.getme');
+ modulemapper.defaults('cordova/testmodule', 'TestClass');
+ modulemapper.mapModules(context);
+ expect(context.num).not.toBe(testmodule);
+ expect(context.obj.str).not.toBe(testmodule);
+ expect(context.getme).not.toBe(testmodule);
+ expect(context.TestClass).not.toBe(testmodule);
+ });
+ it('should throw when namespace is a non-object', function() {
+ expect(function() {
+ modulemapper.merges('cordova/testmodule', 'num');
+ modulemapper.mapModules(context);
+ }).toThrow();
+ });
+ it('should merge into objects', function() {
+ modulemapper.merges('cordova/testmodule', 'obj');
+ modulemapper.mapModules(context);
+ for (var k in testmodule) {
+ if (k != 'subObj') {
+ expect(context.obj[k]).toBe(testmodule[k]);
+ }
+ }
+ expect(context.obj.num).toBe(testmodule.num);
+ expect(context.obj.subObj.num).toBe(9);
+ expect(context.obj.subObj.str).toBe(testmodule.subObj.str);
+ });
+ it('should merge into constructor prototypes', function() {
+ modulemapper.merges('cordova/testmodule', 'TestClass');
+ modulemapper.mapModules(context);
+ for (var k in testmodule) {
+ expect(context.TestClass.prototype[k]).toBe(testmodule[k]);
+ }
+ });
+ it('should maintain order of calls', function() {
+ modulemapper.merges('cordova/testmodule', 'obj');
+ modulemapper.clobbers('cordova/testmodule', 'obj');
+ modulemapper.mapModules(context);
+ expect(context.obj).toBe(testmodule);
+ });
+ it('should maintain order of calls2', function() {
+ modulemapper.merges('cordova/testmodule', 'obj.foo');
+ modulemapper.clobbers('cordova/testmodule', 'obj');
+ modulemapper.merges('cordova/testmodule', 'obj.obj');
+ modulemapper.mapModules(context);
+ expect(context.obj.foo).toBeUndefined();
+ expect(context.obj).toBe(testmodule);
+ expect(context.obj).not.toBe(testmodule.obj);
+ expect(context.obj.obj).toBe(testmodule.obj);
+ });
+ it('should return undefined for getOriginalSymbol("unknown")', function() {
+ expect(modulemapper.getOriginalSymbol(context, 'obj')).toBeUndefined();
+ modulemapper.mapModules(context);
+ expect(modulemapper.getOriginalSymbol(context, 'obj')).toBeUndefined();
+ });
+ it('should remember original symbols when clobbering', function() {
+ var orig = context.obj;
+ modulemapper.clobbers('cordova/testmodule', 'obj');
+ modulemapper.mapModules(context);
+ expect(modulemapper.getOriginalSymbol(context, 'obj')).toBe(orig);
+ });
+});