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/21 19:01:40 UTC

[1/10] 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/master
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);
+    });
+});